您的位置:首页 > 移动开发 > Android开发

Android 如何创建子线程以及区分主线程

2016-11-23 11:35 246 查看
创建子线程的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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息