最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入Android Handler與線程間通信ITC的詳解

 更新時間:2013年05月21日 12:15:46   作者:  
本篇文章是對Android的Handler與線程間通信ITC進行了詳細的分析介紹,需要的朋友參考下
在《Android Handler之消息循環(huán)的深入解析》中談到了Handler是用于操作線程內(nèi)部的消息隊列,所以Handler可以用來線程間通信ITC,這種方式更加安全和高效,可以大大減少同步的煩惱,甚至都可以不用syncrhonized。
線程間通訊ITC
正常情況下函數(shù)調(diào)用棧都會生存在同一個線程內(nèi),想要把執(zhí)行邏輯交換到其他線程可以新建一個Thread,然后start()。另外一種方法就是用ITC,也即用消息隊列來實現(xiàn),線程需要把執(zhí)行邏輯交到其他線程時就向另外的線程的消息隊列發(fā)送一個消息,發(fā)送消息后函數(shù)就此結(jié)束返回,調(diào)用棧也停止。當消息隊列中有了消息時,線程會被喚醒來執(zhí)行處理消息,從而把執(zhí)行邏輯從一個線程轉(zhuǎn)到另外一個線程。這就實現(xiàn)了線程間的通信ITC,與進行間通訊IPC有十分類似的思想。

通常的做法都是,在主線程創(chuàng)建一個Handler,然后在新建線程中使用此Handler與主線程通訊。因為主線程的消息隊列已經(jīng)建好,所以直接創(chuàng)建Handler即可,新建的線程就可以直接使用。
有些情況,需要在多線程之間進行通信,這就要為每個線程都創(chuàng)建MessageQueue和Handler,只要線程能訪問其他線程的Handler就可以與之通信。

要正確的創(chuàng)建Handler,因為Handler要與線程綁定,所以在初始化Handler的時候就要注意:
如果給Handler指定Looper對象new Handler(Looper),那么此Handler便綁定到Looper對象所在的線程中,Handler的消息處理回調(diào)會在那個線程中執(zhí)行。
如果創(chuàng)建線程時不指定Looper對象,那么此Handler綁定到創(chuàng)建此Handler的線程內(nèi),消息回調(diào)處理會在那個線程中執(zhí)行,所以像下面的例子,如果這樣寫:
復(fù)制代碼 代碼如下:

private class CookServer extends Thread {
       private Handler mHandler = new Handler() {
               public void handleMessage(Message msg) {
                     ....
                }
        };

那么,此mHandler會與創(chuàng)建此CookerServer的線程綁定,handleMessage也會運行于其中。顯然,如果是主線程調(diào)用new CookServer(),那么mHandler其實是運行在主線程中的。正確的寫法應(yīng)該是:
復(fù)制代碼 代碼如下:

private class CookServer extends Thread {
       public void run() {
             Looper.prepare();
                 // or new Handler(Looper.myLooper())
                 private Handler mHandler = new Handler() {
                       public void handleMessage(Message msg) {
                     ....
                }
        };

HandlerThread
如果要在一個線程中使用消息隊列和Handler,Android API中已經(jīng)有封裝好了的一個類HandlerThread,這個類已經(jīng)做好了Looper的初始化工作,你需要做的就是重寫其onLooperPrepared()方法,在其中創(chuàng)建Handler:
復(fù)制代碼 代碼如下:

private class DeliverServer extends HandlerThread {
      private Handler mHandler;
      public DeliverServer(String name) {
           super(name);
      }
      @Override
      public void onLooperPrepared() {
            mHandler = new Handler(getLooper()) {
                    public void handleMessage(Message msg) {
                        .....
                    }
             };
       }
}

實例
此實例模擬了一個網(wǎng)絡(luò)訂餐系統(tǒng),客戶點擊“Submit order"來產(chǎn)生一個定單,主線程中負責(zé)收集定單,然后交由CookServer來制作,CookServer在制作完成后會交由DeliverServer來把食物運送到客戶,至此一個定單完成,同時CookServer和DeliverServer會更新狀態(tài)。


復(fù)制代碼 代碼如下:

/**
 * How to attach an Handler to a Thread:
 * If you specify Looper object to Handler, i.e. new Handler(Looper), then the handler is attached to the thread owning
 * the Looper object, in which handleMessage() is executed.
 * If you do not specify the Looper object, then the handler is attached to the thread calling new Handler(), in which
 * handleMessage() is executed.
 * In this example, for class CookServer or DeliverServer, if you write this way:
 *     private class CookServer extends Thread {
  private Handler mHandler;
  private Looper mLooper;

  public CookServer() {
   mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
     ....
    }
       start();
  }
 * then mHandler is attached to thread calling new CookServer(), which is the main thread, so mHandler.handleMessage() will
 * be executed in main thread.
 * To attach mHandler to its own thread, you must put it in run(), or after mLooper is created. For our example, providing
 * mLooper or not won't matter, because new Handler() is called in run(), which is in a new thread.
 */
public class HandlerITCDemo extends ListActivity {
    private static final int COOKING_STARTED = 1;
    private static final int COOKING_DONE = 2;
    private static final int DELIVERING_STARTED = 3;
    private static final int ORDER_DONE = 4;

    private ListView mListView;
    private static final String[] mFoods = new String[] {
 "Cubake",
 "Donut",
 "Eclaire",
 "Gingerbread",
 "Honeycomb",
 "Ice Cream Sanwitch",
 "Jelly Bean",
    };
    private ArrayList<String> mOrderList;
    private TextView mGeneralStatus;
    private Button mSubmitOrder;
    private static Random mRandomer = new Random(47);
    private int mOrderCount;
    private int mCookingCount;
    private int mDeliveringCount;
    private int mDoneCount;

    private Handler mMainHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
     switch (msg.what) {
     case COOKING_STARTED:
  mCookingCount++;
  break;
     case COOKING_DONE:
  mCookingCount--;
  break;
     case DELIVERING_STARTED:
  mDeliveringCount++;
  break;
     case ORDER_DONE:
  mDeliveringCount--;
  mDoneCount++;
     default:
  break;
     }
     mGeneralStatus.setText(makeStatusLabel());
 }
    };

    private CookServer mCookServer;
    private DeliverServer mDeliverServer;

    @Override
    protected void onDestroy() {
 super.onDestroy();
 if (mCookServer != null) {
     mCookServer.exit();
     mCookServer = null;
 }
 if (mDeliverServer != null) {
     mDeliverServer.exit();
     mDeliverServer = null;
 }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 mListView = getListView();
 mOrderList = new ArrayList<String>();
 mGeneralStatus = new TextView(getApplication());
 mGeneralStatus.setText(makeStatusLabel());
 mSubmitOrder = new Button(getApplication());
 mSubmitOrder.setText("Submit order");
 mSubmitOrder.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
  String order = mFoods[mRandomer.nextInt(mFoods.length)];
  mOrderList.add(order);
  mOrderCount = mOrderList.size();
  mGeneralStatus.setText(makeStatusLabel());
  setAdapter();
  mCookServer.cook(order);
     }
 });
 mListView.addHeaderView(mGeneralStatus);
 mListView.addFooterView(mSubmitOrder);
 setAdapter();
 mCookServer = new CookServer();
 mDeliverServer = new DeliverServer("deliver server");
    }

    private String makeStatusLabel() {
 StringBuilder sb = new StringBuilder();
 sb.append("Total: ");
 sb.append(mOrderCount);
 sb.append("    Cooking: ");
 sb.append(mCookingCount);
 sb.append("    Delivering: ");
 sb.append(mDeliveringCount);
 sb.append("    Done: ");
 sb.append(mDoneCount);
 return sb.toString();
    }

    private void setAdapter() {
 final ListAdapter adapter = new ArrayAdapter<String>(getApplication(), android.R.layout.simple_list_item_1, mOrderList);
 setListAdapter(adapter);
    }

    private class CookServer extends Thread {
 private Handler mHandler;
 private Looper mLooper;

 public CookServer() {
     start();
 }

 @Override
 public void run() {
     Looper.prepare();
     mLooper = Looper.myLooper();
     mHandler = new Handler(mLooper, new Handler.Callback() {
  public boolean handleMessage(Message msg) {
      new Cooker((String) msg.obj);
      return true;
  }
     });
     Looper.loop();
 }

 public void cook(String order) {
     if (mLooper == null || mHandler == null) {
  return;
     }
     Message msg = Message.obtain();
     msg.obj = order;
     mHandler.sendMessage(msg);
 }

 public void exit() {
     if (mLooper != null) {
  mLooper.quit();
  mHandler = null;
  mLooper = null;
     }
 }
    }

    private class Cooker extends Thread {
 private String order;
 public Cooker(String order) {
     this.order = order;
     start();
 }

 @Override
 public void run() {
            mMainHandler.sendEmptyMessage(COOKING_STARTED);
            SystemClock.sleep(mRandomer.nextInt(50000));
            mDeliverServer.deliver(order);
            mMainHandler.sendEmptyMessage(COOKING_DONE);
 }
    }

    private class DeliverServer extends HandlerThread {
 private Handler mHandler;

 public DeliverServer(String name) {
     super(name);
     start();
 }

 @Override
 protected void onLooperPrepared() {
     super.onLooperPrepared();
     mHandler = new Handler(getLooper(), new Handler.Callback() {
  public boolean handleMessage(Message msg) {
      new Deliver((String) msg.obj);
      return true;
  }
     });
 }
 public void deliver(String order) {
     if (mHandler == null || getLooper() == null) {
  return;
     }
     Message msg = Message.obtain();
     msg.obj = order;
     mHandler.sendMessage(msg);
 }

 public void exit() {
     quit();
     mHandler = null;
 }
    }

    private class Deliver extends Thread {
 private String order;
 public Deliver(String order) {
     this.order = order;
     start();
 }

 @Override
 public void run() {
     mMainHandler.sendEmptyMessage(DELIVERING_STARTED);
     SystemClock.sleep(mRandomer.nextInt(50000));
     mMainHandler.sendEmptyMessage(ORDER_DONE);
 }
    }
}

相關(guān)文章

  • Android ListView的OnItemClickListener詳解

    Android ListView的OnItemClickListener詳解

    這篇文章主要介紹了Android ListView的OnItemClickListener詳解的相關(guān)資料,涉及到OnItemClickListener的position和id參數(shù)做詳細的解釋的知識點,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2016-07-07
  • 詳解Flutter混排瀑布流解決方案

    詳解Flutter混排瀑布流解決方案

    這篇文章主要介紹了Flutter混排瀑布流解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Android開發(fā)Launcher進程啟動流程

    Android開發(fā)Launcher進程啟動流程

    這篇文章主要為大家介紹了Android開發(fā)Launcher進程啟動流程示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • JNI方法實現(xiàn)圖片壓縮(壓縮率極高)

    JNI方法實現(xiàn)圖片壓縮(壓縮率極高)

    這篇文章主要給大家介紹了一種JNI方法實現(xiàn)圖片壓縮(壓縮率極高)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Android實現(xiàn)自定義華麗的水波紋效果

    Android實現(xiàn)自定義華麗的水波紋效果

    關(guān)于Android的水波紋效果小編之前給大家也分享幾篇類似的,有興趣可通過下面的相關(guān)文章進行查看,今天給大家再分享一個華麗的水波紋效果,這個效果很不錯,感興趣的可以參考借鑒。
    2016-08-08
  • Kotlin的::符號怎么用

    Kotlin的::符號怎么用

    本文主要介紹了Kotlin的::符號怎么用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • OpenGL實現(xiàn)Bezier曲線的方法示例

    OpenGL實現(xiàn)Bezier曲線的方法示例

    今天小編就為大家分享一篇關(guān)于OpenGL實現(xiàn)Bezier曲線的方法示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Android自定義照相機詳解

    Android自定義照相機詳解

    幾乎每個APP都會用的相機功能,下面小編把內(nèi)容整理分享到腳本之家平臺,供大家參考
    2016-04-04
  • Kotlin中的對象表達式和對象聲明的具體使用

    Kotlin中的對象表達式和對象聲明的具體使用

    這篇文章主要介紹了Kotlin中的對象表達式和對象聲明的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Android 中 Activity顯示隱式跳轉(zhuǎn)

    Android 中 Activity顯示隱式跳轉(zhuǎn)

    這篇文章主要介紹了Android 中 Activity顯示隱式跳轉(zhuǎn)的實現(xiàn)方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02

最新評論

阳新县| 辽宁省| 祁门县| 子洲县| 台州市| 呼和浩特市| 永安市| 石首市| 深圳市| 响水县| 辉县市| 大安市| 托克逊县| 酉阳| 灵山县| 邵东县| 宁安市| 中宁县| 临颍县| 尚义县| 崇左市| 土默特右旗| 合作市| 尉氏县| 安泽县| 象州县| 赞皇县| 微山县| 宜川县| 邹平县| 边坝县| 和龙市| 雷州市| 延川县| 临泉县| 津市市| 囊谦县| 芜湖县| 福泉市| 久治县| 邯郸市|