android之Handle異步的消息回調機制

異步的消息回調機制,利用Handle來發送消息和處理消息(消息放於線程消息隊列中)html

應用場景一:android應用UI每隔10秒去請求web端接口,獲取數據庫message消息表中最新的「個人未讀消息」記錄數,並高亮顯示在UI裏
java

習慣了java編程,咱們一開始會試圖用下面的代碼來刷新UIandroid

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

在android平臺開發時這樣是不行的,由於它違背了單線程模型 :Android UI操做並非線程安全的而且這些操做必須在UI線程中執行。
通常藉助Handle則能夠實現這一效果web

 

 

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消息處理機制。其主要原理能夠這樣簡單的理解:數據庫

 

一、建立一個子線程,由它借用主線程裏的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進入時的動畫;ide

 

push_left_in.xmloop

 

<?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對象操做。

相關文章
相關標籤/搜索