背景
以前 android 异步可以用 Handler 和 Thread配合使用,然后在run方法中调用Looper.prepare()和Looper.loop()两个方法。默认情况下android中的新的线程是没有开启消息循环,除了主线程外,主线程会自动创建Looper,开启循环消息。
HandlerThread 是继承Thread,实际上也是一个线程。然后重写run方法,在run方法中实现Looper.prepare()和Looper.loop()方法。
源码
run 方法重写:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
并且还提供一个getLooper方法返回HandlerThread的Lopper对象。
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;
}
除此之外还提供两个退出消息队列的方法:quit()和quitSafely():
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
这两个相同点是: 不接受新的Message加入消息队列中。
- quit: 最后调用removeAllFutureMessagesLocked(),该方法的作用是把MessageQueue消息池中所有的消息全部清空,无论是延迟消息(延迟消息是指通过sendMessageDelayed或通过postDelayed等方法发送的需要延迟执行的消息)还是非延迟消息。
- quitSafely: 最后调用removeAllFutureMessagesLocked(),该方法只会清空MessageQueue消息池中所有的延迟消息,并将消息池中所有的非延迟消息派发出去让Handler去处理,quitSafely相比于quit方法安全之处在于清空消息之前会派发所有的非延迟消息。
实例
处理Message的Handler:
private Handler mMsgHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSG_ONE:
int progress = msg.arg1;
mBar.setProgress(progress);
mText.setText(progress + "%");
break;
}
}
};
创建mHandlerThread:
mHandlerThread = new HandlerThread("handler_thread");
mHandlerThread.start();
//将mHandlerThread的Looper关联到主线程的Handler。
mHandler = new Handler(mHandlerThread.getLooper());
mHandler.post(new Runnable() {
@Override
public void run() {
boolean isRunning = false;
int count = 0;
try {
isRunning = true;
count = 0;
while (isRunning){
count++;
if(count >= 100){
isRunning = false;
}
Message message = Message.obtain();
message.what = MSG_ONE;
message.arg1 = count;
mMsgHandler.sendMessage(message);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
完全代码
public class HandlerThreadActivity extends BaseActivity {
private static final int MSG_ONE = 1;
private Button mBtn;
private TextView mText;
private ProgressBar mBar;
private Handler mHandler;
private HandlerThread mHandlerThread;
private Handler mMsgHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSG_ONE:
int progress = msg.arg1;
mBar.setProgress(progress);
mText.setText(progress + "%");
break;
}
}
};
@Override
protected void loadViewLayout() {
setContentView(R.layout.test_activity_handler_thread);
}
@Override
protected void loadIntent() {
}
@Override
protected void bindViews() {
mBtn = (Button) findViewById(R.id.start);
mText = (TextView) findViewById(R.id.text);
mBar = (ProgressBar) findViewById(R.id.pba);
}
@Override
protected void processLogic(Bundle savedInstanceState) {
}
@Override
protected void setListener() {
findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
test();
}
});
}
private void test(){
mHandlerThread = new HandlerThread("handler_thread");
mHandlerThread.start();
//将mHandlerThread的Looper关联到主线程的Handler。
mHandler = new Handler(mHandlerThread.getLooper());
mHandler.post(new Runnable() {
@Override
public void run() {
boolean isRunning = false;
int count = 0;
try {
isRunning = true;
count = 0;
while (isRunning){
count++;
if(count >= 100){
isRunning = false;
}
Message message = Message.obtain();
message.what = MSG_ONE;
message.arg1 = count;
mMsgHandler.sendMessage(message);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
网友评论