android之Handle异步的消息回调机制

异步的消息回调机制,利用Handle来发送消息和处理消息(消息放于线程消息队列中)

应用场景一:android应用UI每隔10秒去请求web端接口,获取数据库message消息表中最新的“我的未读消息”记录数,并高亮显示在UI里

习惯了java编程,我们一开始会试图用下面的代码来刷新UI

new Thread( new Runnable() {     
    public void run() {     
         myView.invalidate();    
     }            
}).start();

在android平台开发时这样是不行的,因为它违背了单线程模型 :Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
一般借助Handle则可以实现这一效果

 

 

MessageThread thread=new MessageThread();
	thread.isRunning=true;
	thread.start();
	TextView bg=(TextView)layout.findViewById(R.id.tv);
	class MessageThread extends Thread{ 
		public boolean isRunning = true; 
		@Override
		public void run() {
		  while(isRunning){ 
			try {
				//getMsgcount();
		      count=dao.getMsgCount()+"";//往数据库获取未读消息数
			  Message m=new Message();//创建一个新的消息
			  m.what=1;
			  handler.sendMessage(m);//handler发送消息,参数m为1
			  Thread.sleep(10000); 
			} catch (Exception e) {
				e.printStackTrace();
			}
		  }
		}
	}
	
	public Handler handler=new Handler(){
		public void handleMessage(Message msg) {//handleMessage消息处理者执行处理方法
			super.handleMessage(msg);
			if(msg.what==1){
			if(!"".equals(count)&&count!=null){
					int msgcount=Integer.valueOf(count);
					if(msgcount==0){
						bd.hide();
					}else{
		            bd.setText(msgcount+"");
		            bd.show();     }      
		            }
			}
		}
	};

既然无法在子线程中去更新UI,那我们可以借助handler消息处理机制。其主要原理可以这样简单的理解:

 

1、创建一个子线程,由它借用主线程里的handler去发送一个消息给主线程handle.sendMessage(),这个消息会被主线程放入到消息队列里message queue,主线程里会有一个looper对这些消息进行轮询,并调用handler消息处理者,执行handleMessage方法,就可以在handleMessage方法里更新UI了。

应用场景二:handler.postDelayed,实现定时器或延时器。

welcome页面停留两秒后往左侧滑动,进入登录页面

 

public class WelcomeActivity extends FragmentActivity {

	private Handler mHandler;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		setContentView(R.layout.welcome_main);
		mHandler = new Handler();
    	mHandler.postDelayed(new Runnable() {
			@Override
			public void run() {
				Intent intent = new Intent();
		    	intent.setClass(getApplicationContext(), LoginActivity.class);
		    	startActivity(intent);
		    	finish();
		    	overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
			}
    	}, 2000);
    }    
}

public void overridePendingTransition(int enterAnim, int exitAnim);实现两个Activity之间的动画切换,从一个activity跳转到另外一个activity时的动画。
enterAnim是第一个activity退出时的动画;
exitAnim是第二个activity进入时的动画;

 

push_left_in.xml

 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<translate android:fromXDelta="100%p" android:toXDelta="0"
		android:duration="500" />
</set>

push_left_out.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<translate android:fromXDelta="0" android:toXDelta="-100%p"
		android:duration="500" />
</set>

这就实现了延时两秒滑动进入的延时器,如要该装成每个两秒循环执行的定时器,只需稍作改动。

mHandler = new Handler();
Runnable runnable=new Runnable(){
   @Override
   public void run() {
    // TODO Auto-generated method stub
    //要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
   mHandler.postDelayed(this, 2000);
   }
};
mHandler.postDelayed(runnable, 2000);
//mHandler.removeCallbacks(runnable);

核心就是将Runnable提取出来,外层调用mHandler.postDelayed(runnable, 2000);run方法里面再调用mHandler.postDelayed(this, 2000);

 

若要实现每次时间累积,如第一次延时2秒,第二次延时4秒,可以考虑用static对象操作。

posted @ 2016-10-29 18:42  海的心  阅读(431)  评论(0编辑  收藏  举报