Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 初級開發 >> Android 從現實生活中理解線程消息機制

Android 從現實生活中理解線程消息機制

編輯:初級開發

android 有一種叫消息隊列的說法,這裡我們可以這樣理解:假如一個隧道就是一個消息隊列,那麼裡面的每一部汽車就是一個一個消息,這裡我們先忽略掉超車等種種因素,只那麼先進隧道的車將會先出,這個機制跟我們android 的消息機制是一樣的。

android 的線程消息機制

android 在設計的時候引入了 wince 的消息機制,即將每一個消息發送到隊列裡面,遵循先進先出原則。發送消息並不會阻塞線程,而接收線程會阻塞線程,這是因為 android 的Handler 機制,當Handler 處理完一個 Message 對象才會接著去取下面一個消息進行處理,如下圖:

這裡記住:android裡並沒有Global的Message Queue數據結構,例如,不同APK裡的對象不能透過Massage Queue來交換訊息(Message)。例如:線程A的Handler對象可以傳遞消息給別的線程,讓別的線程B或C等能送消息來給線程A(存於A的Message Queue裡)。線程A的Message Queue裡的訊息,只有線程A所屬的對象可以處理。

案例分析:

經典的歌詞同步,這時我們不僅要聽到優質的歌曲,還要可以有歌詞同步,這時另開一條線程來處理歌詞的同步是比較好的解決辦法,你可以根據自己的定義,抓取歌曲的duration 在線程中處理歌詞的前進或者後退。。。

Demo 分析:

下面我們來實現一個Iphone 上的一個通過按數字後,數字過多消除的按鈕事件。事件的原理如下,事件要的效果是這樣的,當長按消除按鈕後,數字會慢慢消除,過會消除速度會增快,那麼實現這個效果我們就需要自己做一個小鍵盤,我做的鍵盤效果如下:

我們通過點擊

來達到這個效果,使用的是android 的線程機制。實現代碼如下:

private Thread thread;

private TextVIEw tv_call_no;

protected static Runnable Runablerun = null;

private Handler handler;

private int textLength = 0;

private boolean isStop = true;

首先將要使用的數據類型聲明在頭部,將會使用到 Java 的 Thread 和android Handler 對象,首先實現Runable 對象,代碼如下:

Runablerun = new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

try {

int i = 0;

do {

i++;

Thread.sleep(i > 15 ? 20 : 100);

Message msg = handler.obtainMessage();

msg.arg1 = i;

msg.sendToTarget();

if (i == textLength) {

isStop = false;

}

} while (isStop);

} catch (Exception e) {

// TODO: handle exception

}

}

};

上面代碼還可以如此寫法:

Message msg=new Message();

msg.arg1=i;

handler.sendMessage(msg);

第一種寫法是message 從handler 類獲取,從而可以直接向該handler 對象發送消息,第二種寫法是直接調用 handler 的發送消息方法發送消息。不過不管是第一種方法好還是第二種方法好,都要在同樣的handler 接收消息,否則會報異常。下面實現handler 對象,代碼如下:

/**

* 啟動線程

*

* @param tv

* @param text

* @return

*/

public Handler getHandler(final TextVIEw tv, final String text) {

Handler hand = new Handler() {

public void handleMessage(Message msg) {

tv.setText(text.substring(0, text.length() - msg.arg1));

super.handleMessage(msg);

};

};

return hand;

}

這裡返回一個handler 對象,實際上是返回去給上面我們的handler 對象使用,這裡我把它封裝成一個方法,可以讓它在每次接收到消息後去使用消息處理文本每次減1

設置

的 onTouch 事件,使其在彈出時停止遞減:

/**

* 點擊back刪除之前的數據,跳出就停止刪除

*/

OnTouchListener ontouch = new OnTouchListener() {

@Override

public boolean onTouch(VIEw v, MotionEvent event) {

// TODO Auto-generated method stub

String text = tv_call_no.getText().toString();

if (text.length() == 0) {

isStop = false;

return false;

}

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

isStop = true;

textLength = tv_call_no.getText().length();

handler = getHandler(tv_call_no, text);

thread = new Thread(Runablerun);

thread.start();

break;

case MotionEvent.ACTION_UP:

isStop = false;

break;

}

return false;

}

};

小結:

1、向哪個Handler 發送消息,就必須在哪個handler 裡面接收;

2、直接使用Java 的 Thread 是無法更新Android UI的,因為Android VIEw 在設計的時線程是不完全的,不過android 提供了幾種供開發者在線程中更新UI的方法,如下:

Activity.runOnUiThread( Runnable )

VIEw.post( Runnable )

VIEw.postDelayed( Runnable, long )

Hanlder

3、直接使用hanlder .post 等方法是在當前主線程裡面做操作,而不是另外新建線程,建議使用Thread 線程直接新建另外一個線程或者使用HandlerThread類也可以。

4、記住消息隊列的先進先出原則。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved