異步的消息回調機制,利用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對象操做。