Android UI 单线程模型和AsyncTask原理【转】

      在Android开发中经常会用到从网络上访问资源,从数据库中查询信息,如果我们单击界面上的某一个控件的时候执行这些操作,如果网络资源不可用,数据库操作消耗时间过长,就会使我们的程序一直进入阻塞状态,用户感觉程序已经死掉,如果长时间没反应,用户可能还要重启系统。这样用户体验不好,为了解决这个问题,我们想对这些操作在开一个线程让他们后台运行,防止主线程进入阻塞状态。这种情况下就涉及了android UI及时更新,用一个progressBar或者一个progressDialog提示用户后台执行的情况。

这中间涉及一个问题:

当Android程序第一次执行的启动的时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责与UI相关的事件,如:用户点击事件,触屏事件及屏幕重绘事件,并把相关的事件分发到对应的组件进行处理。所以主线程又称UI线程。在开发Android应用的时候必须遵守Android UI 单线程模型原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

解决这种情况有两种方案:

1.用线程和Handler机制:在线程里面做后台操作,在Handler里面进行控件及时更新。

2.用AsyncTask原理:AsyncTask是一个工具类,适合于简单的异步处理,不需要借助线程和Handler。

 

AsyncTask和Handler对比

1 ) AsyncTask实现的原理,和适用的优缺点

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:

l  简单,快捷

l  过程可控       

使用的缺点:

l  在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

2 )Handler异步实现的原理和适用的优缺点

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message-àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

使用的优点:

l  结构清晰,功能定义明确

l  对于多个后台任务时,简单,清晰

使用的缺点:

l  在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

 

例子.线程和Handler机制

 1 package com.example.uithread;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.os.Message;
 7 import android.util.Log;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 import android.widget.ProgressBar;
12 public class HandlerTestActivity extends Activity {
13     /** Called when the activity is first created. */
14     private ProgressBar progressBar;
15     private Button button;
16     private int i;
17     @Override
18     public void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.activity_main);
21         progressBar = (ProgressBar) findViewById(R.id.proBar);
22         button = (Button) findViewById(R.id.button);        
23 
24         button.setOnClickListener(new OnClickListener() {
25    
26             @Override
27             public void onClick(View v) {
28                 // TODO Auto-generated method stub
29                 i = 0;
30                 new Thread(mThread).start();
31             }
32         });        
33     }
34   
35     Handler mHandler = new Handler(){
36         
37         @Override
38         public void handleMessage(Message msg) {
39             // TODO Auto-generated method stub   
40             progressBar.setVisibility(View.VISIBLE);
41             mHandler.post(mThread);
42 
43             if(msg.arg1>=100){
44                 update();
45                 mHandler.removeCallbacks(mThread);
46             }
47             
48             super.handleMessage(msg);
49         }     
50     };
51         
52     Runnable mThread = new Runnable() {
53         
54         @Override
55         public void run() {
56             // TODO Auto-generated method stub
57             
58             //放一些后台操作代码但是具体咋放自己感觉
59             Message message =     new Message();
60             message.arg1    =    (i+=10);
61             mHandler.sendMessage(message);
62             try {
63                 Thread.sleep(500);
64             } catch (InterruptedException e) {
65                 // TODO Auto-generated catch block
66                 e.printStackTrace();
67             }
68         }
69     };
70    
71     public void update(){
72         progressBar.setVisibility(View.GONE);
73     }
74 }
View Code

xml文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 4     android:orientation="vertical"
 5     android:layout_width="fill_parent"
 6     android:layout_height="fill_parent"
 7     >
 8 <TextView  
 9     android:layout_width="fill_parent" 
10     android:layout_height="wrap_content" 
11     android:text="你好"
12     />
13 <Button 
14      android:id="@+id/button"
15      android:layout_width="fill_parent"
16      android:layout_height="wrap_content"
17      android:text="执行后台操作"/>
18 <ProgressBar 
19      android:id="@+id/proBar"
20      android:layout_gravity="center"
21      android:layout_width="wrap_content"
22      android:layout_height="wrap_content"
23      android:visibility="gone"/>
24 </LinearLayout>
View Code

 

posted on 2013-05-16 15:12  林盛  阅读(320)  评论(0)    收藏  举报