Android中handler的用法实例

Android中handler的用法实例

经常可以碰到费时的操作或者其他线程需要更新UI的情况,这时候就需要用到handler机制来实现线程间的通信。

Handler主要用于不同线程之间的通信,尤其是普通线程通过handler机制发送message给主线程(UI线程)来更新UI,或者是把耗时的操作发送给service让service来执行。

Handler主要处理的对象有两种:一种是message,一种是runable

Handler具体介绍请看---------------->>>>>>


Handler有四种构造函数:

1:Handler()

2:Handler(Callback callback)

3:Handler(Looper looper)

4:Handler(Looper looper, Callback callback)


Handler有两类主要的发送信息的方法:

1:boolean post(Runnable r)                    //发送一个Runnable对象,并执行该对象的run方法。(特别注意:这个对象是在handler的所在的线程中运行)

2:boolean sendMessage(Message msg)    //发送一个message信息,让handleMessage方法来处理
如果对Looper不熟悉---------------->>>>>>

本文分别对这四种构造函数进行一个简单的总结O O。


一:Handler()

代码一:sendMessage(Message msg)实现Thread发送message到UI线程(主线程)的handler来更新UI的方法

把Message送入消息队列,handler机制自动循环取出数据用handleMessage方法来处理,可以根据Message的what属性来进行分支语句选择。

我们把Handler和Thread的方法实现都单独拿出来变成一个类,这样可以方便重用和让代码更加清晰一些O O

MainActivity.java

public class MainActivity extends Activity {

	private Button startButton;
	private TextView showTextView;
	private Handler myhandler1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mainlayout);
		startButton = (Button)findViewById(R.id.btn_st);
		showTextView = (TextView)findViewById(R.id.tv_show);
		myhandler1 = new MyHandler(MainActivity.this);
	
		startButton.setOnClickListener(new View.OnClickListener() {	
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				new MyThread(myhandler1).start();
			}
		});
		
		
		
	}
	public void updareTheUI(){
		//do some updating operate
		showTextView.setText("success!!");
	}

}


 MyHandler.java
public class MyHandler extends Handler {
	private MainActivity mainActivity;
	
	public  MyHandler(MainActivity main) {
		super();
		mainActivity=main;
	}
	@Override
	public void handleMessage(Message msg) {
		// TODO Auto-generated method stub
		super.handleMessage(msg);
		
		int what = msg.what;
		switch (what) {
		case 1:
			updareTheUI();
			break;

		default:
			break;
		}
		
	}
	private void updareTheUI(){
		//mainActivity.updareTheUI();
	}
}
MyThread.java

public class MyThread extends Thread {
	private Handler handler;
	public MyThread(Handler h){
		handler=h;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		
		//run方法
		Message message = Message.obtain();
		message.what=1;
		handler.sendMessage(message);
		//run方法
	}
}

代码二:post(runable r)实现用handler来重复运行一个runable对象

(Ps.如果费时的操作或者网络,数据库操作是不行的,因为本质上还是运行在同一个线程中,调用的是run方法而不是start方法)


简单的把所有代码写在同一类中,方便内部类调用外部类的实例

public class MainActivity extends Activity {

	private Button startButton;
	private TextView showTextView;
	private Handler myhandler1;
	private Button stop;
	Runnable runnable;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mainlayout);
		showTextView  = (TextView)findViewById(R.id.tv_show);
		myhandler1=new Handler();
	    runnable = new Runnable()
	    {
	        public void run()
	        {

	            showTextView.append(" Go ");
	            //延时1s后又将线程加入到线程队列中
	            myhandler1.postDelayed(runnable, 1000);
	            //或者先sleep(1000);然后myhandler1.post(runnable); 一样的效果
	        }
	    };
	    myhandler1.post(runnable);
	
		//手动停止按钮
	    stop = (Button)findViewById(R.id.btn_stop);
	    stop.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				myhandler1.removeCallbacks(runnable);
			}
		});
	    
	}

}


二:Handler(Callback callback)----------实现handMessage方法的重用

Callback时Handler类内部的一个接口:

    public interface Callback {
        public boolean handleMessage(Message msg);
    }
他仅仅要求实现一个handleMessage的方法。

代码三:

class myCallback implements Handler.Callback{

	@Override
	public boolean handleMessage(Message arg0) {
		// TODO Auto-generated method stub
		//do something
		if(arg0.what==1)
			return true;
		else
			return false;
	}
	
}

public class MainActivity extends Activity {

        private Handler myhandler1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mainlayout);

                myhandler1=new Handler(new myCallback());
		new Thread(){
			public void run() {
				myhandler1.sendMessage(Message.obtain(myhandler1,1));
			};
		}.start();
	  
	}

}
个人简单的理解:其实这个方法和直接继承Handler并重写handleMessage方法没什么太大的不同O O

无非是,你的handleMessage方法可以重用到别处,或是如何。。。

或者说,根据Handler源代码中的dispathMessage方法,这个机制的作用就是一层一层的传递这个消息,这个消息能被哪一层的消息处理函数handleMessage来处理。

比如,你创建了一个Handler,然后别人需要扩展你的handler的时候,可以直接调用这种构造方法来实现他的特别的处理机制。

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }



三:Handler(Looper looper)

不知道你是否有所疑问,为什么主线程可以接受并处理message的消息,并不断的循环提取message。或是是否所有的线程都可以创建一个Handler对象。

1:普通线程变成Looper线程

普通需要在run方法中添加两个函数才能变成一个Looper线程:只有绑定了对应的Looper才可以使用Handler对象,并处理消息。

代码三:

    class myThread extends Thread {  
          public Handler mHandler;  
      
          public void run() {  
              //先准备,准备会new一个messageQueue来存放消息
              Looper.prepare();  
      
              mHandler = new Handler() {  
                  public void handleMessage(Message msg) {  
                      // process incoming messages here  
                  }  
              };  
              //loop()相当于开启了message收取的循环
              Looper.loop();  
          }  
      }  
这样子一个普通线程就成为了一个Looper线程,线程内可以直接创建Handler来处理消息。

2:主线程(UI线程)

一个程序的主线程是怎么来的呢?

程序运行时,AcitivityManager会产生一个新的进程,这个新进程会先创建一个ActivityThread实例,在ActivityThread实例中就会创建并绑定对应的Looper,

之后才启动我们看到的Activity界面。


使用:

这个构造函数一般结合Looper.getMainLooper()来使用,Looper.getMainLooper()用于获取主线成的Looper,

所以,new Handler(Looper.getMainLooper())就可以得到一个关联主线程的Handler实例。


自己随便想出来的一个奇怪的Handler(Looper looper)的实例:主线程发送信息给其他线程,让其他线程来处理费时信息。。

代码四:

class MyThread extends Thread{
    private Looper myLooper;
    private Handler h;
    @Override
    public void run() {
        // TODO Auto-generated method stub
    	synchronized (myLooper) {
            Looper.prepare();  
            myLooper = Looper.myLooper();
		}

        Looper.loop(); 
        
    }
    public Looper getLooper() {
        return myLooper;
    }
}

public class MainActivity extends Activity {

    private Button startButton;
    private TextView showTextView;
    private Handler myhandler1;
    private Button stop;
    private int x=0;
    Runnable runnable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainlayout);
        showTextView  = (TextView)findViewById(R.id.tv_show);
        
        MyThread thread = new MyThread();
        thread.start();
        Looper looper=null;
        while(looper==null){
            looper = thread.getLooper();
        }
        Log.i("MyLooper", looper.toString());
        Log.i("main", Looper.getMainLooper().toString());
        myhandler1 = new Handler(looper){
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                Log.i(Thread.currentThread().getName(),Thread.currentThread().getName()+"-"+"haha"+x);
                //我们可以在这个新线程中做一些费时的计算或者处理一类的操作。。
                //因为整个Handler其实是MainActivity的内部类,所以可以方便的直接调用MainActivity内的实例。
            }
        };
        for(int i = 0 ;i<100;i++)
        {
            Log.i(Thread.currentThread().getName(),Thread.currentThread().getName());
            myhandler1.sendMessage(Message.obtain());

        }
    }

}



四:Handler(Looper looper, Callback callback)

第四中构造函数相当与2和3的结合。其实根据上面的例子我们可以发现Handler函数最重要的实例就是Looper实例,最重要的处理消息的方法就是handleMessage方法,这个构造函数相当于是直接在构造的时候就把整个Handler定义好了,不用在去找他的对应线程或是重写handleMessage方法。



总结:Handler的主要功能就是,发送消息和处理消息

主要用来实现异步回调功能,在新线程中做完一个费时的操作后,启动这个回调函数。

更简单的说就是

1,A线程发送消息给A线程,告诉A线程接下来要做什么。。。。代码二

2,A线程发送消息给B线程,告诉B线程接下来要做什么。。。。代码一,代码四

3,异步回调执行一系列操作,或者是重复循环一系列操作。。。。代码二

 

你可能感兴趣的:(Android应用)