【齐天的博客】转载请注明出处(万分感谢!):
https://blog.csdn.net/qijinglai/article/details/80735718
关联文章:
Android多线程(Handler篇)
Android多线程(AsyncTask篇)
Android多线程(HandlerThread篇)
Android多线程(IntentService篇)
在之前Android多线程(Handler篇)中讲解了ThreadLoacl、Looper、Handler、Message之间的关系,在主线程中为我们工作。其实我们可以借鉴UI线程Looper的思想,建一个子线程,也通过Handler、Looper通信,可以适用于很多场景。
主线程中是自带looper的,而在子线程中使用Handler需要自己创建looper,而HandlerThread的注释中说:
Handy class for starting a new thread that has a looper.
The looper can then be used to create handler classes.
Note that start() must still be called.
意思是,使用HandlerThread可以方便的开启一个线程,并且这个线程已经绑定了一个looper了。这个looper可以用来new一个handler类。注意在此之前,要调用start()方法。
很显然HandlerThread可以胜任我们提到的工作。
使用
这里就直接复制鸿洋_写的例子了
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mTvServiceInfo;
private HandlerThread mCheckMsgThread;
private Handler mCheckMsgHandler;
private boolean isUpdateInfo;
private static final int MSG_UPDATE_INFO = 0x110;
//与UI线程管理的handler
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建后台线程
initBackThread();
mTvServiceInfo = (TextView) findViewById(R.id.id_textview);
}
@Override
protected void onResume()
{
super.onResume();
//开始查询
isUpdateInfo = true;
mCheckMsgHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
@Override
protected void onPause()
{
super.onPause();
//停止查询
isUpdateInfo = false;
mCheckMsgHandler.removeMessages(MSG_UPDATE_INFO);
}
private void initBackThread()
{
mCheckMsgThread = new HandlerThread("check-message-coming");
mCheckMsgThread.start();
mCheckMsgHandler = new Handler(mCheckMsgThread.getLooper())
{
@Override
public void handleMessage(Message msg)
{
checkForUpdate();
if (isUpdateInfo)
{
mCheckMsgHandler.sendEmptyMessageDelayed(MSG_UPDATE_INFO, 1000);
}
}
};
}
/**
* 模拟从服务器解析数据
*/
private void checkForUpdate()
{
try
{
//模拟耗时
Thread.sleep(1000);
mHandler.post(new Runnable()
{
@Override
public void run()
{
String result = "实时更新中,当前大盘指数:<font color='red'>%d</font>";
result = String.format(result, (int) (Math.random() * 3000 + 1000));
mTvServiceInfo.setText(Html.fromHtml(result));
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
@Override
protected void onDestroy()
{
super.onDestroy();
//释放资源
mCheckMsgThread.quit();
}
}
布局就是一个TextView。
使用并不是本文重点,下面分析源码。
原理分析
HandlerThread使用一共三步
mCheckMsgThread = new HandlerThread("check-message-coming");
mCheckMsgThread.start();
mCheckMsgHandler = new Handler(mCheckMsgThread.getLooper())
...
...
构造,开启,创建
构造
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
只是调用了父类的初始化方法开了一个线程
开启
调用start()方法,启动一个新线程,新线程会执行相应的run()方法:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
在之前Android多线程(Handler篇)中可以知道:
prepare()中创建了一个Looper对象,并放入ThreadLocal中,在Looper对象的构造过程中,初始化了并绑定了一个MessageQueue。
loop()方法不断的循环从MessageQueue中取消息处理,当没有消息的时候会阻塞,有消息的到来的时候会唤醒。
创建
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
返回了刚刚在run()中创建的mLooper对象
最后值得说一下的是run()中的notifyAll()和getLooper()中的wait();
因为Handler是在主线程初始化的,所以必须等mLooper创建完成才能getLooper(),所以当mLooper==null时getLoop等待一下mLooper初始化,得到以后notifyAll。
---------------------
作者:Qi T
来源:CSDN
原文:https://blog.csdn.net/qijinglai/article/details/80735718
版权声明:本文为博主原创文章,转载请附上博文链接!