日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android官方开发文档Training系列课程中文版:线程执行操作之线程间通讯

發布時間:2024/7/5 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android官方开发文档Training系列课程中文版:线程执行操作之线程间通讯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文地址:http://android.xsoftlab.net/training/multiple-threads/communicate-ui.html

上節課我們學習了如何啟動一項由ThreadPoolExecutor所管理的線程任務。最后這節課我們將學習如何從任務中發送結果數據給UI線程。這項手段可以使任務在執行完畢后將結果顯示到UI中去。

每個APP擁有獨立的UI線程。只有在UI線程中創建的對象才可以訪問該線程中的其它對象。正因為運行任務的線程不是UI線程,所以它們不可以直接訪問UI對象。為了將數據從后臺線程轉移到UI線程,需要使用運行在UI線程中的Handler對象。

在UI線程中定義Handler

Handler是Android系統框架管理線程的一部分。Handler對象專門用于接收消息處理消息。 一般來說,可以為新線程創建一個Handler,也可以為一個已經連接好的線程創建Handler。當你將Handler連接到UI線程時,處理消息的代碼都會運行在UI線程中。

在構建線程池的類的構造方法中實例化一個Handler對象,并將該對象的引用存儲于全局變量中。通過Handler(Looper)重載構造方法所實例化Handler可以與UI線程產生關聯。這個構造方法所使用的Looper參數是Android系統的線程管理框架的另一部分。當以指定的Looper實例初始化一個Handler對象時,Handler對象會運行在Looper對象所在的線程中。

private PhotoManager() { ...// Defines a Handler object that's attached to the UI threadmHandler = new Handler(Looper.getMainLooper()) {...

在Handler內,重寫handleMessage()方法。Android系統會在Handler所管理的線程中接收到一條新的消息時回調該方法:

/** handleMessage() defines the operations to perform when* the Handler receives a new Message to process.*/@Overridepublic void handleMessage(Message inputMessage) {// Gets the image task from the incoming Message object.PhotoTask photoTask = (PhotoTask) inputMessage.obj;...}...} }

將數據從非UI線程轉移到UI線程

為了將數據從后臺進程轉移到UI進程,首先將數據的引用以及UI對象存儲于任務對象中。接下來,將該任務對象及狀態碼傳給由Handler對象所初始化的對象。在這個對象內,發送一條包含狀態碼的任務對象給Handler。因為Handler是運行在UI線程的,所以它可以將數據交給UI對象。

存儲數據于任務對象中

舉個例子,這里有一個Runnable對象,運行于后臺線程,它用于解碼一個Bitmap對象,并將其存儲于它所屬的對象PhotoTask中。該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 arraybyte[] imageBuffer = mPhotoTask.getByteBuffer();...// Runs the code for this taskpublic void run() {...// Tries to decode the image bufferreturnBitmap = BitmapFactory.decodeByteArray(imageBuffer,0,imageBuffer.length,bitmapOptions);...// Sets the ImageView BitmapmPhotoTask.setImage(returnBitmap);// Reports a status of "completed"mPhotoTask.handleDecodeState(DECODE_STATE_COMPLETED);...}... } ...

PhotoTask還包含了一個用于展示Bitmap的ImageView的句柄。盡管引用Bitmap以及ImageView的是同一個對象,但是還是不能將Bitmap賦值給ImageView,因為當前并沒有處在UI線程中。

發送狀態到對象層級

PhotoTask在層級內處于第二高度。它維護了圖像的解碼數據以及一個View對象。它會接收PhotoDecodeRunnable中的狀態碼,并將其傳給維護線程池以及Handler的那個對象。

public class PhotoTask {...// Gets a handle to the object that creates the thread poolssPhotoManager = 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 methodhandleState(outState);}...// Passes the state to PhotoManagervoid 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,然后通過這個Message對象將狀態以及人物對象發送給Handler:

public class PhotoManager {...// Handle status messages from taskspublic void handleState(PhotoTask photoTask, int state) {switch (state) {...// The task finished downloading and decoding the imagecase 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()中檢查每條消息的狀態。如果消息的狀態為TASK_COMPLETE,那么表明該任務已經終結,那么Message中所包含的PhotoTask對象包含了一個Bitmap以及一個ImageView。因為Handler.handleMessage()是運行在UI線程的,所以它可以安全的將Bitmap賦給ImageView:

private PhotoManager() {...mHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message inputMessage) {// Gets the task from the incoming Message object.PhotoTask photoTask = (PhotoTask) inputMessage.obj;// Gets the ImageView for this taskPhotoView localView = photoTask.getPhotoView();...switch (inputMessage.what) {...// The decoding is donecase TASK_COMPLETE:/** Moves the Bitmap from the task* to the View*/localView.setImageBitmap(photoTask.getImage());break;...default:/** Pass along other messages from the UI*/super.handleMessage(inputMessage);}...}...}...} ... }

總結

以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:线程执行操作之线程间通讯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。