标签:des   android   c   style   class   code   
多线程与UI线程间通信
向你展示如何从任务发送数据对象上运行用户界面(UI)线程。该特性允许你的任务做背景的工作结果,然后再到UI元素如位图。
       
每个应用程序都有自己的特殊的线程运行的UI对象如视图对象; 
这个线程称为UI线程。只有在UI线程上运行对象访问其他线程的对象。因为你的任务运行在一个线程从一个线程池不是UI线程上运行,他们没有对UI对象的访问。将数据从一个后台线程到UI线程,使用Handler的UI线程上运行。
在UI线程上定义一个Handler
Handler是Android系统的框架的一部分来管理线程。Handler对象接收消息并运行代码来处理这些消息。正常地,您为了一个新线程创建一个Handler 
,但你也能创建一个Handler连接到一个现有的线程。当你连接一个Handler到你的UI线程,处理消息的代码在UI线程上运行。
 
例子:一个Handler对象类的构造函数中创建你的线程池, 
并将对象存储在一个全局变量。它连接到UI线程通过实例化Handler(Looper)构造函数。这个构造函数使用一个Looper对象,这是另一个Android系统的线程管理框架的一部分。当你实例化一个基于特定的Looper实例的Handler对象,Handler 
就像
Looper一样运行在相同的线程
代码例子:
  
  
    | 
      private PhotoManager() {...// Defines a Handler 
      object that‘s attached to the UI thread
 mHandler = new 
      Handler(Looper.getMainLooper()) {...
 | 
里面的Handler,重写了handlerMessage()方法。Android系统调用此方法收到新消息时,线程的管理;所有的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;
 ...
 }...}
 }
 The next section shows how to tell the
 Handlerto move data. | 
后台线程与UI线程交换数据
运行在后台的线程任务与UI线程交换数据,首先引用数据和UI对象存储在任务对象。接下来,通过任务对象和一个状态码来实例化的对象处理程序。在这个对象,包含状态和任务对象发送一个消息Handler。因为Handler是在UI线程上运行,它可以将数据移动到UI对象。.
 
在任务对象存储数据
例如, 这里有一个 Runnable
  
  
    | // A class that decodes photo files into Bitmapsclass 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也包含一个处理ImagVie显示位图。尽管引用同一个对象的bitmap和ImageView,, 
你不能分配ImageView的位图, 因为你不是目前在UI线程上运行。
相反,下一步是把这状态发送到PhotoTask对象。
发送状态的对象层次结构
PhotoTask 在层次结构中是下一个更高的对象。它维护引用的解码数据和视图对象将显示数据。它从PhotoDecodeRunnable接收状态代码,并将它传递到维护线程池和实例化的对象处理程序:
  
  
    | 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
从PhotoTask对象,PhotoManager对象接收状态代码和PhotoTask对象的句柄。因为状态TASK_COMPLETE,创建一个消息包含状态和任务对象并将它发送到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()检查每个传入消息的状态码。如果TASK_COMPLETE状态代码,然后,任务完成后,PhotoTask对象在消息中包含一个位图和一个ImageView。因为Handler.handleMessage()在UI线程上运行,它可以安全地移动ImageView位图:
  
  
    | private PhotoManager() {...
 mHandler = new Handler(Looper.getMainLooper()) {
 @Override
 public void handleMessage(Message inputMessage) {
 // Gets the task from the incoming Message object.
 PhotoTask photoTask = (PhotoTask) inputMessage.obj;
 // Gets the ImageView for this task
 PhotoView localView = photoTask.getPhotoView();
 ...
 switch (inputMessage.what) {
 ...
 // The decoding is done
 case 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);
 }
 ...
 }
 ...
 }
 ...
 }
 ...
 }
  | 
 
 
Hander,布布扣,bubuko.com
Hander
标签:des   android   c   style   class   code   
原文地址:http://www.cnblogs.com/orangebook/p/3654564.html