亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

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

2020-04-11 12:22:50
字體:
來源:轉載
供稿:網友
在《Android Handler之消息循環的深入解析》中談到了Handler是用于操作線程內部的消息隊列,所以Handler可以用來線程間通信ITC,這種方式更加安全和高效,可以大大減少同步的煩惱,甚至都可以不用syncrhonized。
線程間通訊ITC
正常情況下函數調用棧都會生存在同一個線程內,想要把執行邏輯交換到其他線程可以新建一個Thread,然后start()。另外一種方法就是用ITC,也即用消息隊列來實現,線程需要把執行邏輯交到其他線程時就向另外的線程的消息隊列發送一個消息,發送消息后函數就此結束返回,調用棧也停止。當消息隊列中有了消息時,線程會被喚醒來執行處理消息,從而把執行邏輯從一個線程轉到另外一個線程。這就實現了線程間的通信ITC,與進行間通訊IPC有十分類似的思想。

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

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

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

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

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中已經有封裝好了的一個類HandlerThread,這個類已經做好了Looper的初始化工作,你需要做的就是重寫其onLooperPrepared()方法,在其中創建Handler:
復制代碼 代碼如下:

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) {
                        .....
                    }
             };
       }
}

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


復制代碼 代碼如下:

/**
 * 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);
 }
    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久99青青精品免费观看| 国产一区二区在线免费| 亚洲国产成人精品一区二区| 日韩免费观看在线观看| 欧美一级电影免费在线观看| 91在线观看欧美日韩| 国产亚洲精品91在线| 欧美美女18p| 91在线观看免费高清| 欧美午夜影院在线视频| 欧美性在线视频| 成人在线激情视频| 亚洲精品720p| 亚洲国产精品一区二区三区| 久久久女女女女999久久| 欧美专区日韩视频| 国产不卡精品视男人的天堂| 国模私拍视频一区| 超在线视频97| 久久久久久久久久亚洲| 久久久久久免费精品| 国产97人人超碰caoprom| 欧美肥老太性生活视频| 欧美夫妻性生活视频| 在线成人一区二区| 亚洲精品国产精品乱码不99按摩| 欧美高清不卡在线| 在线观看日韩欧美| 国产精品香蕉国产| 日韩免费av一区二区| 日韩av电影手机在线| 亚洲精品国产综合区久久久久久久| 久久久久久久久久久国产| 亚洲国产一区自拍| 精品视频偷偷看在线观看| 国产精品电影观看| 91日本在线视频| 亚洲精品一区二区三区婷婷月| 中文.日本.精品| 亚洲美女黄色片| 久久久久久久影视| 8050国产精品久久久久久| 91经典在线视频| 欧美极品欧美精品欧美视频| 久久精品中文字幕电影| 亚洲精品99久久久久中文字幕| 国产成人精品优优av| 亚洲色图欧美制服丝袜另类第一页| 欧美电影免费观看电视剧大全| 国产精品久久一| 国产午夜精品视频免费不卡69堂| 狠狠躁18三区二区一区| 国产精品美女主播| 疯狂做受xxxx高潮欧美日本| 日韩视频在线观看免费| 国产精品你懂得| 538国产精品一区二区在线| 国产xxx69麻豆国语对白| 欧美美最猛性xxxxxx| 日韩一区视频在线| 欧美日韩人人澡狠狠躁视频| 日韩精品有码在线观看| 亚洲欧美色婷婷| 91精品国产91久久久久久最新| 日韩最新在线视频| 韩国福利视频一区| 国产成人一区二区| 国外色69视频在线观看| 亚洲国产欧美自拍| 成人a免费视频| 在线日韩av观看| 中文字幕在线精品| 亚洲天堂网站在线观看视频| 日韩资源在线观看| 成人免费淫片aa视频免费| 国产成人精品在线| 国产成人综合精品在线| 久久色在线播放| 欧美xxxx做受欧美.88| 国产精品亚洲аv天堂网| 日韩高清有码在线| 亚洲影院色在线观看免费| 日韩在线观看免费高清完整版| 欧美日韩亚洲视频| 欧美精品电影免费在线观看| 91久久精品国产| 久久中国妇女中文字幕| 亚洲精品中文字| 免费97视频在线精品国自产拍| 欧美日韩另类字幕中文| 欧美日韩一区二区在线| 日韩在线观看电影| 色综合久久悠悠| 亚洲一区二区精品| 亚洲理论在线a中文字幕| 国产午夜精品理论片a级探花| 成人精品久久久| 欧美激情一二区| 亚洲中国色老太| zzijzzij亚洲日本成熟少妇| 亚洲天堂av网| 亚洲精品自拍偷拍| 国产欧美日韩免费看aⅴ视频| 国产精品www色诱视频| 日韩免费视频在线观看| 高清在线视频日韩欧美| 成人在线视频福利| 欧美日韩成人免费| 成人免费在线视频网站| 欧美日韩高清区| 国产成人一区二区三区小说| 91美女片黄在线观看游戏| 91在线观看欧美日韩| 久久香蕉频线观| 久久91精品国产| 这里精品视频免费| 日本免费在线精品| 4p变态网欧美系列| 亚洲一区二区三区视频播放| 精品国产福利视频| 日韩av免费在线看| 欧美日韩亚洲国产一区| 亚洲自拍偷拍第一页| 中文字幕日韩在线视频| 欧美另类69精品久久久久9999| 久久久久久亚洲| 欧美在线视频免费| 国产精品777| 中文字幕亚洲欧美一区二区三区| 欧美福利视频在线观看| 高清欧美性猛交xxxx| 日韩视频免费在线| 欧美成人第一页| 日本精品免费一区二区三区| 欧美精品videossex88| 久热99视频在线观看| 久久精品这里热有精品| 成人免费观看49www在线观看| 亚洲精品乱码久久久久久按摩观| 欧美男插女视频| 中文字幕欧美日韩va免费视频| 在线观看久久久久久| 国产成人精品最新| 久久久精品中文字幕| 九九热在线精品视频| 亚洲人成在线电影| 亚洲第一视频在线观看| 欧美日韩国产中文字幕| 日韩精品视频在线免费观看| 久久91精品国产91久久跳| 国产不卡在线观看| 国产乱肥老妇国产一区二| 97在线免费观看| 亚洲欧洲av一区二区| 日韩免费高清在线观看| 在线成人中文字幕| 菠萝蜜影院一区二区免费| 久热精品视频在线观看一区| 黄色一区二区三区| 精品久久久久人成| 国产精品久久91| 国产精品一区二区三区毛片淫片| 在线视频中文亚洲| 日韩视频在线一区|