展会信息港展会大全

Android线程模型和AsyncTask
来源:互联网   发布日期:2016-01-14 12:43:00   浏览:1031次  

导读:的线程模型:当一个 android 的应用运行后,就会有一个 UI 的 main 线程启动 , 这是一个非常重要的线程,它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与 a...

的线程模型:当一个 android 的应用运行后,就会有一个 UI 的 main 线程启动 , 这是一个非常重要的线程,它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与 android 控件 交互的线程。比如,当你在屏幕上的 EditText 上输入文字, UI 线程会把这个事件分发给刚输入文字的 EditText ,紧接会向事件队列发送一个更新 ( invalidate )请求。 UI 线程会把这个请求移出事件队列并通知 EditText 在屏幕上重新绘制自身。

这种单线线程模型就会使得 android 的应用程序性能低下, 如果在这个单线程里执行一些耗时的操作, 比如访问数据库, 或是从网络端下载图片, 就会会阻塞整个用户界面。 比如如下操作:

1 Bitmap b =loadImageFromNetwork();

EE

这个操作非常耗时, 在这种情况下你会发现 , 界面僵死在那里并且 android 在系统 5 秒中后没有反应,会显示一个关闭或等待的错误。www.2cto.com

也许我们可以使用一个新的 Thread 来解决它

1 new Thread(new Runnable() {

2public void run() {

3Bitmap b = loadImageFromNetwork();

4mImageView.setImageBitmap( b );

5}

6 }).start();

但这样会发生一些很难察觉的错误, 因为我们知道 UI 线程不是线程安全的。当然有很多种方法来处理这个问题:

android 提供了几种在其他线程中访问 UI 线程的方法。

Activity.runOnUiThread( Runnable )

View.post( Runnable )

View.postDelayed( Runnable, long )

Hanlder

1 new Thread( new Runnable() {

2public void run() {

3final Bitmap b = loadImageFromNetwork();

4mImageView.post( new Runnable() {

5mImageView.setImageBitmap( b );

6 });

7}

8 }).start();

这种方法比较繁琐,同时当你需要实现一些很复杂的操作并需要频繁地更新UI 时这会变得更糟糕。为了解决这个问题,android 提供了一个工具类:AsyncTask ,它使创建需要与用户界面交互的长时间运行的任务变得更简单。

就拿加载网络图片举个例子:

01 ublic class CanvasImageTask extends AsyncTask<ImageView, Void, Bitmap>{

02private ImageView gView ;

03

04protected Bitmap doInBackground(ImageView... views) {

05Bitmap bmp = null ;

06ImageView view = views[0];

07// 根据iconUrl获取图片并渲染,iconUrl的url放在了view的tag中。

08if (view.getTag() != null) {

09try {

10URL url = new URL(view.getTag().toString());

11HttpURLConnection conn = (HttpURLConnection)url.openConnection();

12conn.setDoInput(true);

13conn.connect();

14InputStream stream = conn.getInputStream();

15bmp = BitmapFactory.decodeStream(stream);

16stream.close();

17} catch (Exception e) {

18Log.v("img", e.getMessage());

19return null;

20}

21}

22this.gView = view;

23return bmp;

24}

25protected void onPostExecute(Bitmap bm) {

26if (bm != null) {

27this.gView.setImageBitmap(bm);

28this.gView = null ;

29}

30}

31

32 }

33 在Activity中直接调用

34 if(!img.isDrawingCacheEnabled() || !holder.image.getTag().equals(imgpath)){

35img.setImageResource(R.drawable.icon_app);

36img.setTag(imgpath);

37try{

38new CanvasImageTask().execute(img);

39img.setDrawingCacheEnabled(true);

40}catch (Exception e) {

41Log.e("error", "RejectedExecutionException in content_img: " +imgpath);

这样图片加载使用异步线程便不会进行堵塞发生错误,我们还可以使用 callback 在图片加载完后进行回调

01 public class CanvasImageTaskCall extends AsyncTask<ImageView, Void, Bitmap> implements Callback{

02private ImageView gView ;

03

04protected Bitmap doInBackground(ImageView... views) {

05Bitmap bmp = null ;

06ImageView view = views[0];

07// 根据iconUrl获取图片并渲染,iconUrl的url放在了view的tag中。

08if (view.getTag() != null) {

09try {

10URL url = new URL(view.getTag().toString());

11HttpURLConnection conn = (HttpURLConnection)url.openConnection();

12conn.setDoInput(true);

13conn.connect();

14InputStream stream = conn.getInputStream();

15bmp = BitmapFactory.decodeStream(stream);

16stream.close();

17} catch (Exception e) {

18e.printStackTrace();

19Log.v("img", e.getMessage());

20Message msg = new Message();

21msg.what = 0;

22handleMessage(msg);

23return null;

24}

25}

26this.gView = view;

27return bmp;

28}

29protected void onPostExecute(Bitmap bm) {

30if (bm != null) {

31this.gView.setImageBitmap(bm);

32this.gView.setTag(bm);

33this.gView = null ;

34Message msg = new Message();

35msg.what = 1;

36handleMessage(msg);

37}

38}

39public boolean handleMessage(Message msg) {

40// TODO Auto-generated method stub

41return false;

42}

43

44 }

在 Activity 中直接调用

01 new CanvasImageTaskCall(){

02@Override

03public boolean handleMessage(Message msg) {

04switch (msg.what) {

05case 0:

06Log.i("test", "图片加载失败");

07break;

08case 1:

09Log.i("test", "图片加载成功");

10break;

11default:

12break;

13}

14saveButton.setTextColor(Color.WHITE);

15saveButton.setClickable(true);

16bitmap = (Bitmap) imageView.getTag();

17return super.handleMessage(msg);

18}

19}.execute(img);

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港