关于UI线程与非UI线程交互,有关Handler机制等(一)
2014-12-02 11:04
281 查看
在Android中,一个activity有一个主线程也叫UI线程,作用就是用来绘制UI界面,在这个线程里面,你的应用和android的UI组件发生交互。所以当你需要进行某些费时操作的时候,比如访问网络等,如果放入UI线程,就会阻塞界面的绘制,当界面不能绘制的时候,整个app看起来就跟卡死一样,更可怕的是,当UI线程挂起时间太长,就会发生ANR。这显然不是一种好的用户体验。另外,UI组件也并不是线程安全的,所以也最好不建议从非UI线程调用UI组件。故我们需要记住以下两点。
1.不要在UI线程里面写费时操作,导致UI线程阻塞
2.不要在非UI线程对绘制界面,可能会导致某些错误
非UI线程也被称作为工作线程,后台线程,我们可以把各种费时的操作写在这里面,比如访问网络等。但是,当我们处理完费时操作的时候,可能需要重新绘制界面(访问UI组件),此时我们就需要让工作线程与UI线程交互。经过总结,有以下五种方式
1.Handler机制
2.Activity.runOnUIThread(Runnable)
3.View.Post(Runnable)
4.View.PostDelayed(Runnable,long)
5.AsyncTask
Handler机制
Handler的核心就是处理消息(Message),Handler存在于主线程且一直存在,等待着子线程(工作线程,非UI线程)处理完问题后返回Message,然后由Handler接收,在主线程处理该Message,并调用响应的UI组件,Message就是UI线程与非UI线程之间的交互信息。
说道Handler,就不得不提Looper和MessageQueue,这也是Handler里面不能缺少的两个部分,Looper英文意思就是环,线程通过Looper建立自己的消息循环,MessageQueue是消息队列,采用先进先出存储消息。Looper负责从MessageQueue中取出消息,并分发到指定的Handler对象。
Handler实现代码
UI线程(只能有一个)
非UI线程
Activity.runOnUIThread(Runnable)
这个可以直接在子线程中写入对UI组件的操作,XActivity.runOnUIThread就能看出,他可以找到对应XActivity的主线程调用UI组件XActivity.currentActivity.runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(getApplicationContext(), , "Update My UI",
Toast.LENGTH_LONG).show();
}
});
View.Post(Runnable)
View.PostDelayed(Runnable,long)
待续
1.不要在UI线程里面写费时操作,导致UI线程阻塞
2.不要在非UI线程对绘制界面,可能会导致某些错误
非UI线程也被称作为工作线程,后台线程,我们可以把各种费时的操作写在这里面,比如访问网络等。但是,当我们处理完费时操作的时候,可能需要重新绘制界面(访问UI组件),此时我们就需要让工作线程与UI线程交互。经过总结,有以下五种方式
1.Handler机制
2.Activity.runOnUIThread(Runnable)
3.View.Post(Runnable)
4.View.PostDelayed(Runnable,long)
5.AsyncTask
Handler机制
Handler的核心就是处理消息(Message),Handler存在于主线程且一直存在,等待着子线程(工作线程,非UI线程)处理完问题后返回Message,然后由Handler接收,在主线程处理该Message,并调用响应的UI组件,Message就是UI线程与非UI线程之间的交互信息。
说道Handler,就不得不提Looper和MessageQueue,这也是Handler里面不能缺少的两个部分,Looper英文意思就是环,线程通过Looper建立自己的消息循环,MessageQueue是消息队列,采用先进先出存储消息。Looper负责从MessageQueue中取出消息,并分发到指定的Handler对象。
Handler实现代码
UI线程(只能有一个)
private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO 接收消息并且去更新UI线程上的控件内容 if (msg.what == 0) { // Bundle b = msg.getData(); // tv.setText(b.getString("num")); tv.setText(String.valueOf(msg.obj)); } super.handleMessage(msg); } };
非UI线程
new Thread() { @Override public void run() { // TODO 子线程中通过handler发送消息给handler接收,由handler去更新TextView的值 try { for (int i = 0; i < 100; i++) { Thread.sleep(500); Message msg = new Message(); msg.what = 0; msg.obj = "更新后的值:" + i; handler.sendMessage(msg); } } catch (InterruptedException e) { e.printStackTrace(); } } }.start();
Activity.runOnUIThread(Runnable)
这个可以直接在子线程中写入对UI组件的操作,XActivity.runOnUIThread就能看出,他可以找到对应XActivity的主线程调用UI组件XActivity.currentActivity.runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(getApplicationContext(), , "Update My UI",
Toast.LENGTH_LONG).show();
}
});
View.Post(Runnable)
View.PostDelayed(Runnable,long)
待续
相关文章推荐
- android UI线程与非UI线程交互(二)
- android基础_ui线程跟非ui线程交互方式
- android UI线程和非UI线程交互(一)
- android UI线程与非Ui线程交互方法
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- android系统中的多线程(一): 关于在android中启动线程以及线程间的交互
- UI线程与非UI线程 android开发
- 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处
- Android UI线程和非UI线程
- C#中后台线程和UI线程的交互
- 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处
- Guava关于JAVA中系统组件之间交互通讯(非线程之间通讯)
- 关于抛出跨线程操作UI线程的异常的处理
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- android系统中的多线程(一): 关于在android中启动线程以及线程间的交互
- 如何实现非ui线程更新ui线程?
- 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处
- Guava关于JAVA中系统组件之间交互通讯(非线程之间通讯)