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

创建子线程的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) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值