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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dalvik/ART(ANDROID)中的多线程机制(1)

發布時間:2023/12/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dalvik/ART(ANDROID)中的多线程机制(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Google參考了Windows的消息處理機制,在Android系統中實現了一套類似的消息處理機制。學習Android的消息處理機制,有幾個概念(類)必須了解:

1.?????? Message

消息,理解為線程間通訊的數據單元。例如后臺線程在處理數據完畢后需要更新UI,則可發送一條包含更新信息的Message給UI線程。

2.?????? Message Queue

消息隊列,用來存放通過Handler發布的消息,按照先進先出執行。

3.?????? Handler

Handler是Message的主要處理者,負責將Message添加到消息隊列以及對消息隊列中的Message進行處理。

4.?????? Looper

循環器,扮演Message Queue和Handler之間橋梁的角色,循環取出Message Queue里面的Message,并交付給相應的Handler進行處理。

?

5.??? 線程

UI thread 通常就是main thread,而Android啟動程序時會替它建立一個Message Queue。

每一個線程里可含有一個Looper對象以及一個MessageQueue數據結構。在你的應用程序里,可以定義Handler的子類別來接收Looper所送出的消息。

?

運行機理:

??????每個線程都可以并僅可以擁有一個Looper實例,消息隊列MessageQueue在Looper的構造函數中被創建并且作為成員變量被保存,也就是說MessageQueue相對于線程也是唯一的。Android應用在啟動的時候會默認會為主線程創建一個Looper實例,并借助相關的Handler和Looper里面的MessageQueue完成對Activities、Services、Broadcase Receivers等的管理。而在子線程中,Looper需要通過顯式調用Looper. Prepare()方法進行創建。Prepare方法通過ThreadLocal來保證Looper在線程內的唯一性,如果Looper在線程內已經被創建并且嘗試再度創建"Only one Looper may be created per thread"異常將被拋出。

?

??????Handler在創建的時候可以指定Looper,這樣通過Handler的sendMessage()方法發送出去的消息就會添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情況下,Handler綁定的是創建它的線程的Looper。如果這個線程的Looper不存在,程序將拋出"Can't create handler inside thread that has not called Looper.prepare()"。

?

??????整個消息處理的大概流程是:1. 包裝Message對象(指定Handler、回調函數和攜帶數據等);2. 通過Handler的sendMessage()等類似方法將Message發送出去;3. 在Handler的處理方法里面將Message添加到Handler綁定的Looper的MessageQueue;4. Looper的loop()方法通過循環不斷從MessageQueue里面提取Message進行處理,并移除處理完畢的Message;5. 通過調用Message綁定的Handler對象的dispatchMessage()方法完成對消息的處理。

?

??????在dispatchMessage()方法里,如何處理Message則由用戶指定,三個判斷,優先級從高到低:1. Message里面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;2. Handler里面mCallback指向的一個實現了Callback接口的對象,由其handleMessage進行處理;3. 處理消息Handler對象對應的類繼承并實現了其中handleMessage函數,通過這個實現的handleMessage函數處理消息。???

?

?

Android的消息機制(一)

?

android 有一種叫消息隊列的說法,這里我們可以這樣理解:假如一個隧道就是一個消息隊列,那么里面的每一部汽車就是一個一個消息,這里我們先忽略掉超車等種種因素,只那么先進隧道的車將會先出,這個機制跟我們android 的消息機制是一樣的。

一、????角色描述

1.Looper:(相當于隧道)一個線程可以產生一個Looper對象,由它來管理此線程里的Message Queue(車隊,消息隧道)。

2.Handler:你可以構造Handler對象來與Looper溝通,以便push新消息到Message Queue里;或者接收Looper(從Message Queue取出)所送來的消息。

3. Message Queue(消息隊列):用來存放線程放入的消息。

4.線程:UI thread通常就是main thread,而Android啟動程序時會替它建立一個Message Queue。

每一個線程里可含有一個Looper對象以及一個MessageQueue數據結構。在你的應用程序里,可以定義Handler的子類別來接收Looper所送出的消息。

?

在你的Android程序里,新誕生一個線程,或執行(Thread)時,并不會自動建立其Message Loop。

Android里并沒有Global的Message Queue數據結構,例如,不同APK里的對象不能透過Massage Queue來交換訊息(Message)。

例如:線程A的Handler對象可以傳遞消息給別的線程,讓別的線程B或C等能送消息來給線程A(存于A的Message Queue里)。

線程A的Message Queue里的訊息,只有線程A所屬的對象可以處理。

使用Looper.myLooper可以取得當前線程的Looper對象。

使用mHandler = new EevntHandler(Looper.myLooper());可用來構造當前線程的Handler對象;其中,EevntHandler是自已實現的Handler的子類別。

使用mHandler = new EevntHandler(Looper.getMainLooper());可誕生用來處理main線程的Handler對象;其中,EevntHandler是自已實現的Handler的子類別。

?

這樣描述可能太抽像,下面舉幾個實際的例子來說明:

二、????舉例

1.??同線程內不同組件間的消息傳遞

Looper類用來管理特定線程內對象之間的消息交換(Message Exchange)。你的應用程序可以產生許多個線程。而一個線程可以有許多個組件,這些組件之間常常需要互相交換訊息。如果有這種需要,您可以替線程構造一個Looper對象,來擔任訊息交換的管理工作。Looper對象會建立一個MessageQueue數據結構來存放各對象傳來的消息(包括UI事件或System事件等)。如下圖:

?

每一個線程里可含有一個Looper對象以及一個MessageQueue數據結構。在你的應用程序里,可以定義Handler的子類別來接收Looper所送出的消息。

同線程不同組件之間的消息傳遞:

publicclass?Activity1extends?Activityimplements?OnClickListener{

?????? Buttonbutton?=null;

?????? TextViewtext?=null;

??????@Override

??????protectedvoid?onCreate(Bundle savedInstanceState) {

?????????????super.onCreate(savedInstanceState);

????????????? setContentView(R.layout.activity1);????????

?????????????button?= (Button)findViewById(R.id.btn);

?????????????button.setOnClickListener(this);

?????????????text?= (TextView)findViewById(R.id.content);

?????? }

??????publicvoid?onClick(View v) {

?????????????switch?(v.getId()) {

?????????????case?R.id.btn:

???????????????????? Looper looper = Looper.myLooper();//取得當前線程里的looper

???????????????????? MyHandler mHandler =new?MyHandler(looper);//構造一個handler使之可與looper通信

????????????????????//buton等組件可以由mHandler將消息傳給looper后,再放入messageQueue中,同時mHandler也可以接受來自looper消息

???????????????????? mHandler.removeMessages(0);

???????????????????? String msgStr ="主線程不同組件通信:消息來自button";

???????????????????? Message m = mHandler.obtainMessage(1, 1, 1, msgStr);//構造要傳遞的消息

???????????????????? mHandler.sendMessage(m);//發送消息:系統會自動調用handleMessage方法來處理消息

????????????????????break;

?????????????? }????????????

?????? }?????

??????privateclass?MyHandlerextends?Handler{?????????????

?????????????public?MyHandler(Looper looper){

????????????????????super(looper);

????????????? }

?????????????@Override

?????????????publicvoid?handleMessage(Message msg) {//處理消息

????????????????????text.setText(msg.obj.toString());

????????????? }????????????

?????? }

}

?

說明:

此程序啟動時,當前線程(即主線程, main thread)已誕生了一個Looper對象,并且有了一個MessageQueue數據結構。

??? looper = Looper.myLooper ();?

調用Looper類別的靜態myLooper()函數,以取得目前線程里的Looper對象.

mHandler = new MyHandler (looper);

構造一個MyHandler對象來與Looper溝通。Activity等對象可以藉由MyHandler對象來將消息傳給Looper,然后放入MessageQueue里;MyHandler對象也扮演Listener的角色,可接收Looper對象所送來的消息。

Message m = mHandler.obtainMessage(1, 1, 1, obj);

先構造一個Message對象,并將數據存入對象里。

mHandler.sendMessage(m);

就透過mHandler對象而將消息m傳給Looper,然后放入MessageQueue里。

此時,Looper對象看到MessageQueue里有消息m,就將它廣播出去,mHandler對象接到此訊息時,會呼叫其handleMessage()函數來處理,于是輸出"This my message!"于畫面上,


總結

以上是生活随笔為你收集整理的Dalvik/ART(ANDROID)中的多线程机制(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

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