创建子线程的DEMO代码:
package com.example.handlerthread;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
Button mMainThread;
Button mSecondThread;
private ClickHandler mClickHandler;
private HandlerThread mHandlerThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainThread = (Button) findViewById(R.id.mainThread);
mSecondThread = (Button) findViewById(R.id.secondThread);
mMainThread.setOnClickListener(this);
mSecondThread.setOnClickListener(this);
mHandlerThread = new HandlerThread("ClickHandler11");//线程名字,方便查询子线程
mHandlerThread.start();
mClickHandler = new ClickHandler(mHandlerThread.getLooper());
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.mainThread:
mClickHandler.sendEmptyMessage(THREAD_WORK_ONE);
if(isMainThread()){//此时还在主线程里,此方法会走
Log.i("lyj_id", "主线程name: "+Thread.currentThread().getName()+" || 主线程ID: "+Thread.currentThread().getId());
}
break;
case R.id.secondThread:
mClickHandler.sendEmptyMessage(THREAD_WORK_TWO);
break;
}
}
//创建子线程
private static final int THREAD_WORK_ONE = 0x01;
private static final int THREAD_WORK_TWO = 0x02;
private class ClickHandler extends Handler {
public ClickHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case THREAD_WORK_ONE://子线程任务1
if(isMainThread()){//此时不在主线程里而是在子线程里,此方法不走
Log.i("lyj_id", "11主线程name: "+Thread.currentThread().getName()+" || 主线程ID: "+Thread.currentThread().getId());
}
ThreadWorkOne();
break;
case THREAD_WORK_TWO://子线程任务2
ThreadWorkTwo();
break;
default:
break;
}
super.handleMessage(msg);
}
}
@Override
public void onDestroy(){
//Avtivity 销毁是一定记得关闭子线程!
mClickHandler.removeCallbacks(mHandlerThread);
super.onDestroy();
}
//子线程任务1处理方法
private void ThreadWorkOne(){
Log.i("lyj_id", "*CHILD Thread NAME: "+Thread.currentThread().getName()+" || CHILD Thread TID: "+Thread.currentThread().getId());
}
//子线程任务2处理方法
private void ThreadWorkTwo(){
Log.i("lyj_id", "#CHILD Thread NAME: "+Thread.currentThread().getName()+" || CHILD Thread TID: "+Thread.currentThread().getId());
}
//判断当前是否是主线程 方法1
public boolean isMainThread() {
return Looper.getMainLooper() == Looper.myLooper();
}
//判断当前是否是主线程 方法2
public boolean isMainThread2() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
//判断当前是否是主线程 方法3
public boolean isMainThread3() {
return Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();
}
}
上面的代码是创建子线程的demo,打印的LOG如下:
I/lyj_id (21345): *CHILD Thread NAME: ClickHandler11 || CHILD Thread TID: 784
I/lyj_id (21345): 主线程name: main || 主线程ID: 1
判断是否是主线程代码里面提供了三种方法,都可以去做判断验证。
可以看出,子线程创建成功,而且在onClick方法中仍然是UI主线程的操作,所以主线程的LOG会走,但在创建子线程的任务中主线程的LOG是不会走的。
所以,此DEMO验证创建子线程的成功和否是是主线程的判断。
另外:当你需要finish一个页面的时候,这个页面有子程序不断的在后台进行运行,finish只能关闭主线程,但是却无法关闭子线程,所以提供以下两种方法:
方法一:在不断循环运行的子线程中加入一个标示符进行判断,当你需要退出的时候,将标示符置为true即可
方法二:利用Android中的handler
//可以用HandlerThread,将它的Looper给handler就可以,具体用法如下:
HandlerThread handlerThread=new HandlerThread("threadTag");
handlerThread.start();
Handler handler=new Handler(handlerThread.getLooper());
handler.post(test);
//这样test不会阻塞ui线程,test为Runnable的子类
在activity的onDestroy()方法中handler.removeCallbacks(test)