Android线程模型--在子线程中更新UI
2015-12-25 17:03
411 查看
Android是支持多线程的。主线程也称UI线程,子线程也称工作线程。一般耗时操作在子线程中进行,更新UI操作在主线程中进行。在主线程中执行耗时操作容易发生ANR错误,即应用程序无响应。而Android中又规定只有创建UI的线程才能更新UI,即只有主线程才能更新UI。然后,我们又听说有什么方法可以子线程中也可以更新UI。
在子线程中更新UI的方法有:
1)Activity类:public void runOnUiThread(Runable action);
2)View类:public boolean post(Runable action);
3)View类:public boolean postDelayed(Runable action,long delayMillis);
可是AndroidUI线程模型不是明确表示子线程中不能更新UI吗?这是怎么回事?结合例子,我们来看一下。
第一种在子线程中更新UI的方法:
--------------------------------------------------------------------------
第二种在子线程中更新UI的方法:
第三种与第二种类似。
子线程是不允许更新UI的,而这些方法从源代码的角度似乎是在子线程中更新UI,其实是间接的调用的主线程更新UI,并不是真的在子线程中更新UI。其主线程与子线程之间的通信采用的是消息机制。
查看其源代码可知,
---------------------------------------------------------
本质上都是调用了Handler中的post()实现线程间通信,而Handler的post()系列方法使用Runnable作为参数,其实质还是调用Handler发消息的方法实现线程间通信。
在子线程中更新UI的方法有:
1)Activity类:public void runOnUiThread(Runable action);
2)View类:public boolean post(Runable action);
3)View类:public boolean postDelayed(Runable action,long delayMillis);
可是AndroidUI线程模型不是明确表示子线程中不能更新UI吗?这是怎么回事?结合例子,我们来看一下。
第一种在子线程中更新UI的方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivImage=(ImageView) findViewById(R.id.imageView1); //handler=new InnerHandler(); handler=new Handler(new InnerCallback()); } public class InnerCallback implements Handler.Callback{ @Override public boolean handleMessage(Message msg) { if(msg.what==LOAD_IMAGE_COMPLETED){ ivImage.setImageBitmap(bm); } return false; } }
--------------------------------------------------------------------------
第二种在子线程中更新UI的方法:
public void doLoadImage(View v){ //子线程调用View的post()方法更新ui new Thread(){ public void run() { //从网络中加载图片,即耗时操作 final Bitmap bm=loadImageFromNetwork(); ivImage.post(new Runnable() { @Override public void run() { //更新图片显示 ivImage.setImageBitmap(bm); } }); }; }.start(); }
第三种与第二种类似。
子线程是不允许更新UI的,而这些方法从源代码的角度似乎是在子线程中更新UI,其实是间接的调用的主线程更新UI,并不是真的在子线程中更新UI。其主线程与子线程之间的通信采用的是消息机制。
查看其源代码可知,
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }
---------------------------------------------------------
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Assume that post will succeed later ViewRootImpl.getRunQueue().post(action); return true; }
本质上都是调用了Handler中的post()实现线程间通信,而Handler的post()系列方法使用Runnable作为参数,其实质还是调用Handler发消息的方法实现线程间通信。
相关文章推荐
- Loadrunner中参数化实战(1)-Sequential+Each iteration
- Java GUI
- Android ui 测试课堂笔记
- requestLayout和invalidate方法的区别
- Servlet(Response,Request)
- Android ui 测试课堂笔记
- Java UUID
- 使用burpsuite_pro_v1.6破解版暴力破解实例
- leetcode -- Range Sum Query 2D - Immutable -- 简单DP题目
- Webdriver UI自动化测试使用mybatis访问数据库
- UITableView - beginUpdates和endUpdates方法
- windows2008 nps+802.1
- UIViewController各个方法的加载顺序
- UIButton
- 05 Stacks and Queues
- Implement Queue using Stacks 用俩栈实现队列
- iOS开发-简述UITableView中cell的重用问题
- iOS UITableView(一)tableView的创建
- ios UIAlertController 的用法
- How to create a customized field value by executing PHP code