Android——线程创建以及handler

一:创建子线程:

1:通过继承Thread类,并改写run方法来实现一个线程

new mThread().start();

public class mThread extends Thread
{
		@Override
		public void run(){
			System.out.print("继承Thread类,实现run方法");
		}
};


2:创建Runnable类对象并复写Run()方法创建线程:

新建一个线程如下:

new Thread(mThread).start();

  1. Runnable mThread = new Runnable(){  
  2.        @Overrde  
  3.         public void run()  
  4.         {  
  5.           system.out.println(“实现一个Runnable类,并实现Run方法”);  
  6.          }  
  7. };

注意:Runnable是一个接口,不是一个线程,一般线程会实现Runnable。 所以如果我们使用匿名内部类是运行在UI主线程的,如果我们使用实现这个Runnable接口的线程类,则是运行在对应线程的。

Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:


Handler mHandler=new Handler();
mHandler.post(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
}
});

通过调用handler的post方法,把Runnable对象(一般是Runnable的子类)传过去;handler会在looper中调用这个Runnable的Run方法执行。



二:子线程运作:


(1) Activity.runOnUiThread(Runnable) 


在UI线程里运行指定的动作,如果当前线程是UI线程,则立刻被执行
,如果是主线程,则该动作被发送到UI线程的事件队列中,等待处理。

activity.runOnUiThread(new Runnable() { 
@Override 
public void run() { 
// TODO Auto-generated method stub 
int i = 30;
textView.setText(""+i+" s");
}
} 
}); 


(2) Handler 

Handler的定义:

  * 主要接受子线程发送的数据, 并用此数据配合主线程更新UI。当应用程序启动时,

  * Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说,

  * 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。

  * 如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,

  * 如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。

  * 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,

  * 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就出现了,来解决这个复杂的问题 ,

  * 由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,

  * 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象(里面包含数据),把这些消息放入主线程队列中,配合主线程进行更新UI。

Handler一些特点:

  * Handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),

  * 它有两个作用: (1): 安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行

  * Handler中分发消息的一些方法

  * post(Runnable)

  * postAtTime(Runnable,long)

  * postDelayed(Runnable,long)

  * sendEmptyMessage(int)

  * sendMessage(Message)

  * sendMessageAtTime(Message,long)

  * sendMessageDelayed(Message,long)

  * 以上post类方法允许你排列一个Runnable对象到主线程队列中,

       当需要在不同于主UI线程中执行则需要配合HandlerThread进行使用:


Android中Handler的使用,一般都在UI主线程中执行,因此在Handler接收消息后,处理消息时,不能做一些很耗时的操作,否则将出现ANR错误Android中专门提供了HandlerThread类,来解决该类问题。HandlerThread类是一个线程专门处理Hanlder的消息,依次从Handler的队列中获取信息,逐个进行处理,保证安全,不会出现混乱引发的异常。HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量


package cn.wzg.activity;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

public class HandlerTest extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  System.out.println("activity.............."
    + Thread.currentThread().getId());
  System.out.println("activity.name.............."
    + Thread.currentThread().getName());
  //
  HandlerThread handlerthread = new HandlerThread("handler_thread");
  handlerthread.start();

  Myhandler myhandler = new Myhandler(handlerthread.getLooper());
  Message msg = myhandler.obtainMessage();

  Bundle b = new Bundle();
  b.putString("username", "lvjian");
  b.putString("password", "zhanghaiyan");
  msg.setData(b);

  msg.sendToTarget();
 }

 class Myhandler extends Handler {

  public Myhandler() {
   super();
   // TODO Auto-generated constructor stub
  }

  public Myhandler(Looper looper) {
   super(looper);
   // TODO Auto-generated constructor stub
  }

@Override
  public void handleMessage(Message msg) {

   String username = (String) msg.getData().getString("username");
   System.out.println("handler.............."
     + Thread.currentThread().getId() + username);
   System.out.println("handler.name.............."
     + Thread.currentThread().getName());
   super.handleMessage(msg);
  }

 }

}


Handler 与谁相关联不是看声明在什么地方,是看与哪个线程的looper挂钩。默认是主线程的looper.因为主线程中默认就有了looper,消息循环队列

 

Android SDK中的方法说明:

//用于返回与该线程相关联的Looper对象

public Looper getLooper ()


//获得该线程的Id

public int getThreadId ()


//结束当前的Looper 循环。

public boolean quit ()


//用于looper取出的消息处理

public void run ()


handler自己有几种方式

1,用来处理消息和线程,每个handler实例关联一个单线程和该线程 的一个消息队列。


2,handler可以执行一个线程对象(Runnable实例)也可以发送和处理消息

如下:

public class MainActivity extends Activity implements OnClickListener{
	public static final String TAG = "MainActivity";
	
	private Handler mHandler;
	
	private boolean mRunning = false;
	
	private Button mBtn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		HandlerThread thread = new HandlerThread("MyHandlerThread");
		thread.start();//创建一个HandlerThread并启动它
		mHandler = new Handler(thread.getLooper());//使用HandlerThread的looper对象创建Handler,如果使用默认的构造方法,很有可能阻塞UI线程
		mHandler.post(mBackgroundRunnable);//将线程post到Handler中
		
		mBtn = (Button)findViewById(R.id.button);
		mBtn.setOnClickListener(this);
	}
	@Override
	protected void onResume() {
		super.onResume();
		mRunning = true;
	}
	@Override
	protected void onStop() {
		super.onStop();
		mRunning = false;
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	//实现耗时操作的线程
	Runnable mBackgroundRunnable = new Runnable() {
		
		@Override
		public void run() {
			//----------模拟耗时的操作,开始---------------
			while(mRunning){

				Log.i(TAG, "thread running!");
				
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			//----------模拟耗时的操作,结束---------------
		}
	};
	@Override
	protected void onDestroy() {
		super.onDestroy();
		//销毁线程
		mHandler.removeCallbacks(mBackgroundRunnable);
		
	}
	@Override
	public void onClick(View v) {
		Toast.makeText(getApplication(), "click the button!!!", Toast.LENGTH_SHORT).show();
	}
}
销毁线程:

mHandler.removeCallbacks(mBackgroundRunnable);




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值