现在的位置: 首页 > 综合 > 正文

Android 应用软件开发(十)Handler使用

2012年12月04日 ⁄ 综合 ⁄ 共 4985字 ⁄ 字号 评论关闭

使用Handler管理线程

步骤:

1. 申请一个Handler对象

Handler handler = new Handler();

2. 创建一个线程

{继承Thread类或者实现Runnable这个接口}

使用Runnable创建一个内部匿名类对象updateThread(要复写run方法)

3. 使用handler的post方法将线程加入到线程队列中

handler.post(updateThread);

4. 使用handler的removeCallbacks方法移出updateThread线程

注意:如果线程从线程队列中出来被执行后,则队列中就不在有线程

因此如果线程在被执行后没有方法将其再次加入到队列中,则无需使用removeCallbacks

线程走出线程队列有两种情况:

一种是被执行,此时要执行run方法

一种是使用removeCallbacks方法,此时线程不被执行,因此不调用run

5. 使用handler的postDelayed方法延时将线程加入到队列中

handler.postDelayed(updateThread,3000)

下面给出一个简单的代码:

package my.handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class HandleruseActivity extends Activity {
    /** Called when the activity is first created. */
	//声明两个控件变量
	private Button startButton = null;
	private Button endButton = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //获取控件对象
        startButton = (Button)findViewById(R.id.startButton);
        endButton = (Button)findViewById(R.id.endButton);
        
//        设置监听器
        startButton.setOnClickListener(new startListener());
        endButton.setOnClickListener(new endListener());
    }
    class startListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
//			将线程updateThread加入到线程队列中
			handler.post(updateThread);
		}
    }
    class endListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
//			将线程updateThread移出线程队列
			handler.removeCallbacks(updateThread);
		}
    	
    }
    
//    申请handler对象
    Handler handler = new Handler();

//    创建一个线程,线程被调用时一定是调用其run函数
  /*  Runnable updateThread = new Runnable(){
    	public void run(){
    		System.out.println("UpdateThread");
//    		延迟三秒之后将线程updateData加入到线程队列当中
    		handler.postDelayed(updateThread, 3000);
    	}
    };*/
//    继承Runnable 或者继承 Thread
    Thread updateThread = new Thread(){
    	public void run(){
    		System.out.println("UpdateThread Thread");
//    		延迟三秒之后将线程updateData加入到线程队列当中
    		handler.postDelayed(updateThread, 3000);
    	}
    };
}
package progressBar.handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class ProgressBarHandlerActivity extends Activity {
    /** Called when the activity is first created. */
	private Button startButton = null;
	private ProgressBar bar = null;
	int i=0;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startButton = (Button)findViewById(R.id.startButton);
        bar = (ProgressBar)findViewById(R.id.bar);
        startButton.setOnClickListener(new startListener());
    }
	class startListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			bar.setVisibility(View.VISIBLE);
			handler.post(updateBar);
		}
	}
	
//	handler内部实现一个匿名内部类,重载消息处理函数
//	当消息从队列中被取出的时候调用handleMessage函数处理消息
//	这样做的好处是使用参数arg1效率比较高
	Handler handler = new Handler(){
		public void handleMessage(Message msg){
			bar.setProgress(msg.arg1);
			handler.post(updateBar);
		}
	};
	
	Thread updateBar = new Thread(){
		public void run(){
			System.out.println("Begin Thread!");
			i=i+1;
			Message msg = handler.obtainMessage();
			msg.arg1=i;
			try{
				Thread.sleep(1000);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
//			发送消息,将消息加入到消息队列中
			handler.sendMessage(msg);
		if(i==100)
		{
			handler.removeCallbacks(updateBar);
		}
		}
	};
}

注意:用post方法将线程对象放到队列里面执行,并没有开启一个新的线程,而是直接调用线程

对象的run方法,因此并没有实现线程的异步。

解决的办法是先生成一个HandlerThread对象,启动它(start)

使用handlerThread对象的getLooper方法取得其looper对象,注意在此之前必须要start,否则这个

looper是空的

并将looper对象作为参数传递给handler对象,使得这个handler对象绑定到这个Looper所在线程上面

此时需要重写handler类的构造函数,将looper对象传给父类

Looper:类,提供一种循环的从队列当中取得消息的功能,不要自己创建

这样,这个handler就可以循环的从Message消息队列中不断取消息。

下面使用这个办法的代码:

package handler.extr;

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 HandlerExtrActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
//        生成一个HandlerThread对象,此对象实现了使用Looper来处理消息队列的功能
        HandlerThread handlerThread = new HandlerThread("handler-thread");
//        启动线程
        handlerThread.start();
        MyHandler myHandler = new MyHandler(handlerThread.getLooper());
        Message msg0 = myHandler.obtainMessage();
        Bundle b = new Bundle();
        b.putInt("age", 25);
        b.putString("name","xiaocheng");
        msg0.setData(b);
        msg0.arg1=0;
//        将消息发送到目标对象,所谓目标对象就是生成该msg对象的handler对象
        msg0.sendToTarget();
        System.out.println("Activity--->"+Thread.currentThread().getId());
    }
//    要实现消息的处理则需要继承复写handleMessage方法
//    一旦使用继承,则需要重写构造函数传送Looper参数
    class MyHandler extends Handler{
    	public MyHandler(){
    		
    	}
    	public MyHandler(Looper looper){
    		super(looper);
    	}
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			int age = msg.getData().getInt("age");
			String name = msg.getData().getString("name");
			System.out.println("handler--->"+Thread.currentThread().getId());
			System.out.println("My name is "+name+", and my age is "+age);
			System.out.println("msg ---- agr1 is "+msg.arg1);
			try{
				Thread.sleep(1000);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
			super.handleMessage(msg);
			
		}
    	
    }
}

抱歉!评论已关闭.