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 }
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>
浙公网安备 33010602011771号