編輯:Android開發實例
本節向你展示如何在任務中發送數據給UI線程裡的對象,這個特性允許你在後台線程工作,完了在UI線程展示結果。
在UI線程定義一個Handler
Handler是Android系統線程管理框架裡的一部分。一個Handler對象接收消息,並且運行代碼來處理消息。正常情況下,你為新線程創建Handler,但你也可以為已有的線程創建一個Handler.當你連接Handler到UI線程時,處理消息的代碼會在UI線程上運行.
在創建線程池的類的構造器裡實例化Handler對象,保存在全局變量裡。用Handler(Looper)方法實例化,連接到UI線程,構造方法使用Looper對象,也是Android系統線程管理框架裡的一部分.Looper類有一個靜態方法getMainLooper()可以獲取UI線程的Looper對象。如:
代碼如下:
private PhotoManager() {
...
// Defines a Handler object that's attached to the UI thread
mHandler = new Handler(Looper.getMainLooper()) {
...
在Handler裡,覆蓋handleMessage()。Android系統會在Handler管理的線程收到新消息時,調用該方法。一個指定線程的所有Handler對象都會收到相同的消息。
代碼如下:
/*
* handleMessage() defines the operations to perform when
* the Handler receives a new Message to process.
*/
@Override
public void handleMessage(Message inputMessage) {
// Gets the image task from the incoming Message object.
PhotoTask photoTask = (PhotoTask) inputMessage.obj;
...
}
...
}
}
從任務裡移動數據到UI線程
要從後台線程的任務裡移動數據到UI線程的對象,先保存引用到數據和任務對象的UI對象裡,接下來把任務對象和狀態碼傳給Handler對象。在這個對象裡,發送一個包含狀態 和任務對象的消息給Handler.因為Handler在UI線程上運行,它可以移動數據給UI對象。
在任務對象裡存儲數據
如,這是一個Runnable,運行在後台線程,它解析Bitmap,並保存到它的父對象。Runnable同時保存狀態碼DECODE_STATE_COMPLETED。
代碼如下:
// A class that decodes photo files into Bitmaps
class PhotoDecodeRunnable implements Runnable {
...
PhotoDecodeRunnable(PhotoTask downloadTask) {
mPhotoTask = downloadTask;
}
...
// Gets the downloaded byte array
byte[] imageBuffer = mPhotoTask.getByteBuffer();
...
// Runs the code for this task
public void run() {
...
// Tries to decode the image buffer
returnBitmap = BitmapFactory.decodeByteArray(
imageBuffer,
0,
imageBuffer.length,
bitmapOptions
);
...
// Sets the ImageView Bitmap
mPhotoTask.setImage(returnBitmap);
// Reports a status of "completed"
mPhotoTask.handleDecodeState(DECODE_STATE_COMPLETED);
...
}
...
}
...
PhotoTask還包含一個ImageView引用,用來顯示Bitmap.盡管引用Bitmap和ImageView是在同一個對象裡,但因為不是在UI線程,你不能直接讓ImageView顯示Bitmap.
沿對象層次逐級發送狀態
PhotoTask持有解碼的數據和顯示數據的View對象的引用,它從PhotoDecodeRunnable接收到狀態碼,並且沿著線程池裡引用的對象和Handler實例傳送。
代碼如下:
public class PhotoTask {
...
// Gets a handle to the object that creates the thread pools
sPhotoManager = PhotoManager.getInstance();
...
public void handleDecodeState(int state) {
int outState;
// Converts the decode state to the overall state.
switch(state) {
case PhotoDecodeRunnable.DECODE_STATE_COMPLETED:
outState = PhotoManager.TASK_COMPLETE;
break;
...
}
...
// Calls the generalized state method
handleState(outState);
}
...
// Passes the state to PhotoManager
void handleState(int state) {
/*
* Passes a handle to this task and the
* current state to the class that created
* the thread pools
*/
sPhotoManager.handleState(this, state);
}
...
}
移動數據到UI
PhotoManager從PhotoTask對象接收到狀態碼和PhotoTask對象的句柄。因為狀態是TASK_COMPLETE,創建一個包含狀態和任務對象的Message,發送給Handler。
代碼如下:
public class PhotoManager {
...
// Handle status messages from tasks
public void handleState(PhotoTask photoTask, int state) {
switch (state) {
...
// The task finished downloading and decoding the image
case TASK_COMPLETE:
/*
* Creates a message for the Handler
* with the state and the task object
*/
Message completeMessage =
mHandler.obtainMessage(state, photoTask);
completeMessage.sendToTarget();
break;
...
}
...
}
最終,Handler.handleMessage()為每個進來的Message檢查狀態碼。如果狀態碼是TASK_COMPLETE,任務就是完成了,Message裡的PhotoTask對象包含Bitmap和ImageView.因為Handler.handleMessage()運行在UI線程,它可以安全地為ImageView設置Bitmap.
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
當前比較成熟一點的應用基本上都會在進入應用之顯示一個啟動界面.這個啟動界面或簡單,或復雜,或簡陋,或華麗,用意不同,風格也不同.下面來觀摩幾個流行的應用的啟動界面