Android线程
来源:互联网 发布:淘宝宝贝宣言词怎么写 编辑:程序博客网 时间:2024/06/06 18:37
概述
HandlerThread就是可以处理消息循环的线程,它是一个拥有Looper的线程,可以处理消息循环。简单理解就是一个Thread,内部使用了Looper。
我们都知道,除了在主线程,其他线程必须通过Looper.prepare()创建Looper、Looper.loop()开启消息循环。
举个栗子:
import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity { private Button mBtnStart; private Handler mChildThreadHandler; //子线程的Handler @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread thread = new ChildThread(); thread.start(); mBtnStart = (Button)findViewById(R.id.btn_start); mBtnStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mChildThreadHandler.sendEmptyMessage(0); } }); } class ChildThread extends Thread{ @Override public void run(){ Looper.prepare(); //给线程创建一个消息循环 mChildThreadHandler = new Handler(){ @Override public void handleMessage(Message msg){ super.handleMessage(msg); mBtnStart.setText("更新按钮文本"); } }; Looper.loop(); //开始消息循环 } }}
我的天,在Handler更新UI,出现如下异常。
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
提示只有创建视图(主线程)的线程才能更新UI。mChildThreadHandler是在子线程中开启消息循环,所以没办法切换到主线程中更新UI。
HandlerThread就是在Thread中开启消息循环,但为什么要使用HandlerThread呢?当把Looper转到子线程处理,可以减轻主线程的工作量,使主界面更流畅。
再举一个栗子
用一个Handler更新UI,另一个Handler用于异步耗时任务
布局这里就不贴了,就一个Button一个TextView
import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity { private Button mBtnStart; private TextView mTvShow; private Handler mChildHandler; //子线程的Handler private HandlerThread mHandlerThread; //创建异步HandlerThread private int flag; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTvShow = (TextView)findViewById(R.id.tv_show); mBtnStart = (Button)findViewById(R.id.btn_start); mBtnStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mChildHandler.sendEmptyMessage(0); } }); mHandlerThread = new HandlerThread("handlerThread"); mHandlerThread.start(); mChildHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message message) { //这里执行耗时操作后 更新UI Message msg = Message.obtain(); msg.arg1 = ++flag; msg.what = 0; mUpdateUIHandler.sendMessage(msg); return true; } }); } private Handler mUpdateUIHandler = new Handler(){ @Override public void handleMessage(Message message){ //这里用于更新UI switch (message.what){ case 0: mTvShow.setText("得到的数据"+message.arg1); break; } } };@Overrideprotected void onDestroy() { super.onDestroy(); mHandlerThread.quit();}}
效果
HandlerThread源码
public class More ...HandlerThread extends Thread { int mPriority; int mTid = - ; Looper mLooper; public More ...HandlerThread(String name) { //重点1 super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } public More ...HandlerThread(String name, int priority) { super(name); mPriority = priority; } protected void More ...onLooperPrepared() { } @Override public void More ...run() { //重点2 mTid = Process.myTid(); Looper.prepare(); //重点3 synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); //重点4 mTid = - ; } public Looper More ...getLooper() { if (!isAlive()) { return null; } synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } public boolean More ...quit() { //重点5 Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } public boolean More ...quitSafely() { //重点6 Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } public int More ...getThreadId() { return mTid; } }
HandlerThread是一个Thread,传入的参数就是该线程的名称。
重点3、4通过内部自己创建Looper,开启消息循环,会一直循环,当明确不需要的时候,要记得销毁。
5、6的两个方法分别的作用为:
Looper的quit():将MessageQueue消息池的消息全部清空,无论是延迟消息还是非延迟消息。
Looper的quitSafely():只会清空MessageQueue消息池中所有的延迟消息,那些非延迟的消息会发给Handler去处理。
Looper的quit方法从API Level 1就存在了,但是Looper的quitSafely方法从API Level 18才添加进来。
再次强调:HandlerThread是串行执行,拥有自己的消息队列,不会阻塞UI线程。
- android线程之多线程
- Android(线程一) 线程
- android线程
- android线程
- android线程
- android线程
- Android线程
- android 线程
- android线程
- android线程
- android 线程
- android 线程
- android 线程
- Android线程
- Android线程
- android线程
- Android线程
- android线程
- Android Sqlite 数据库升级
- 在MFC程序中使用控制台输出打印信息(VS2010)
- Golang 入门Hello World
- Python 动态导入对象,importlib.import_module()使用
- [Oracle]if中不能有子查詢
- Android线程
- 去掉navigationcontroller返回键文字
- java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to com.bjsxt.service.UserServiceI
- JAVA7在win10系统的安装使用
- 终端命令查看TensorFlow版本号及路径
- 正则表达式
- Spark的优化(一)---分区
- python运维__fifth_chapter(2)--random module 翻译
- 判断字符串是否为空