androidqueue
1. android 一個線程有幾個message queue
一個線程一個只有一個Message Queue,Message通過MessageQueue.IdleHandler關聯到該線程的Looper上,通過Looper.looper();來處理消息分發到該handler回調。
2. Android進程和線程的區別
Android進程和線程的區別
下面我先介紹下Android進程和線程各是什麼,然後再一一比較區別下
Android進程基本知識:
當一個程序第一次啟動的時候,Android會啟動一個LINUX進程和一個主線程。默認的情況下,所有該程序的組件都將在該進程和線程中運行。 同時,Android會為每個應用程序分配一個單獨的LINUX用戶。Android會盡量保留一個正在運行進程,只在內存資源出現不足時,Android會嘗試停止一些進程從而釋放足夠的資源給其他新的進程使用, 也能保證用戶正在訪問的當前進程有足夠的資源去及時地響應用戶的事件。
我們可以將一些組件運行在其他進程中,並且可以為任意的進程添加線程。組件運行在哪個進程中是在manifest文件里設置的,其中<Activity>,<Service>,<receiver>和<provider>都有一個process屬性來指定該組件運行在哪個進程之中。我們可以設置這個屬性,使得每個組件運行在它們自己的進程中,或是幾個組件共同享用一個進程,或是不共同享用。<application>元素也有一個process屬性,用來指定所有的組件的默認屬性。
Android中的所有組件都在指定的進程中的主線程中實例化的,對組件的系統調用也是由主線程發出的。每個實例不會建立新的線程。對系統調用進行響應的方法——例如負責執行用戶動作的View.onKeyDown()和組件的生命周期函數——都是運行在這個主線程中的。這意味著當系統調用這個組件時,這個組件不能長時間的阻塞主線程。例如進行網路操作時或是更新UI時,如果運行時間較長,就不能直接在主線程中運行,因為這樣會阻塞這個進程中其他的組件,我們可以將這樣的組件分配到新建的線程中或是其他的線程中運行。
Android會根據進程中運行的組件類別以及組件的狀態來判斷該進程的重要性,Android會首先停止那些不重要的進程。按照重要性從高到低一共有五個級別:
1.1前台進程
前台進程是用戶當前正在使用的進程。只有一些前台進程可以在任何時候都存在。他們是最後一個被結束的,當內存低到根本連他們都不能運行的時候。一般來說, 在這種情況下,設備會進行內存調度,中止一些前台進程來保持對用戶交互的響應。
1.2可見進程
可見進程不包含前台的組件但是會在屏幕上顯示一個可見的進程是的重要程度很高,除非前台進程需要獲取它的資源,不然不會被中止。
1.3服務進程
運行著一個通過startService() 方法啟動的service,這個service不屬於上面提到的2種更高重要性的。service所在的進程雖然對用戶不是直接可見的,但是他們執行了用戶非常關注的任務(比如播放mp3,從網路下載數據)。只要前台進程和可見進程有足夠的內存,系統不會回收他們。
1.4後台進程
運行著一個對用戶不可見的activity(調用過 onStop() 方法).這些進程對用戶體驗沒有直接的影響,可以在服務進程、可見進程、前台進 程需要內存的時候回收。通常,系統中會有很多不可見進程在運行,他們被保存在LRU (least recently used) 列表中,以便內存不足的時候被第一時間回收。如果一個activity正 確的執行了它的生命周期,關閉這個進程對於用戶體驗沒有太大的影響。
1.5空進程
未運行任何程序組件。運行這些進程的唯一原因是作為一個緩存,縮短下次程序需要重新使用的啟動時間。系統經常中止這些進程,這樣可以調節程序緩存和系統緩存的平衡。
單線程模型
線程在代碼是使用標準的java Thread對象來建立,那麼在Android系統中提供了一系列方便的類來管理線程——Looper用來在一個線程中執行消息循環,Handler用來處理消息,HandlerThread創建帶有消息循環的線程。具體可以看下面的詳細介紹。
當一個程序第一次啟動時,Android會同時啟動一個對應的主線程(Main Thread),主線程主要負責處理與UI相關的事件,如用戶的按鍵事件,用戶接觸屏幕的事件以及屏幕繪圖事件,並把相關的事件分發到對應的組件進行處理。所以主線程通常又被叫做UI線程。
在開發Android應用時必須遵守單線程模型的原則: Android UI操作並不是線程安全的並且這些操作必須在UI線程中執行。
2.1 子線程更新UI Android的UI是單線程(Single-threaded)的。
為了避免拖住GUI,一些較費時的對象應該交給獨立的線程去執行。如果幕後的線程來執行UI對象,Android就會發出錯誤訊息 。以後遇到這樣的異常拋出時就要知道怎麼回事了!
2.2 Message Queue
在單線程模型下,為了解決類似的問題,Android設計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue並結合Handler和Looper組件進行信息交換。下面將對它們進行分別介紹:
2..3 Message 消息
理解為線程間交流的信息,處理數據後台線程需要更新UI,則發送Message內含一些數據給UI線程。
2.4. Handler 處理者
是Message的主要處理者,負責Message的發送,Message內容的執行處理。後台線程就是通過傳進來的Handler對象引用來sendMessage(Message)。而使用Handler,需要implement 該類的 handleMessage(Message) 方法,它是處理這些Message的操作內容,例如Update UI。通常需要子類化Handler來實現handleMessage方法。
2.5. Message Queue 消息隊列
用來存放通過Handler發布的消息,按照先進先出執行。 每個message queue都會有一個對應的Handler。Handler會向message queue通過兩種方法發送消息:sendMessage或post。這兩種消息都會插在message queue隊尾並按先進先出執行。但通過這兩種方法發送的消息執行的方式略有不同:通過sendMessage發送的是一個message對象,會被Handler的handleMessage()函數處理;而通過post方法發送的是一個runnable對象,則會自己執行。
2.6 Looper Looper是每條線程里的Message Queue的管家。
Android沒有Global的Message Queue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程里並沒有建立Message Queue。所以調用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調用Looper.myLooper()得到當前線程的Looper就有可能為NULL。
從以上幾點,不難看出Android進程和線程的二者的區別所在。
3. android怎麼實現任務隊列
主要就是有一個線程隊列,維護這些任務,這里沒有用到Queue而是用List是考慮到顯示的問題。
4. Android中如何將queue中的值放入textview
具體操作如下:
Button bt =(Button)findViewById(R.id.button1);
TextView tx=(TextView)findViewById(R.id.textView1);
tx.setText(bt.getText());
getText()就是獲取按鈕上的文字,在TextView中顯示出來
5. android中的線程池 怎麼用
Java的線程池對Android也是適用的
線程池的作用:
線程池作用就是限制系統中執行線程的數量。
根據系統的環境情況,可以自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制線程數量,其他線程
排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務需要運行時,如果線程
池中有等待的工作線程,就可以開始運行了;否則進入等待隊列。
為什麼要用線程池:
1.減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。
2.可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把伺服器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)。
Java通過Executors提供四種線程池,分別為:
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
newScheledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行。
1.newCachedThreadPool
/**
* 可以緩存線程池
*/
public static void Function1() {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 50; i++) {
final int index = i;
try {
Thread.sleep(100); // 休眠時間越短創建的線程數越多
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
executorService.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("active count = " + Thread.activeCount()
+ " index = " + index);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
列印結果
active count = 2 index = 0
active count = 3 index = 1
active count = 4 index = 2
active count = 5 index = 3
active count = 6 index = 4
active count = 7 index = 5
active count = 8 index = 6
active count = 9 index = 7
active count = 10 index = 8
active count = 11 index = 9
active count = 11 index = 10
active count = 11 index = 11
active count = 11 index = 12
active count = 11 index = 13
active count = 11 index = 14
active count = 11 index = 15
active count = 11 index = 16
active count = 11 index = 17
active count = 11 index = 18
active count = 11 index = 19
active count = 11 index = 20
active count = 11 index = 21
active count = 11 index = 22
active count = 11 index = 23
active count = 11 index = 24
active count = 11 index = 25
active count = 11 index = 26
active count = 11 index = 27
active count = 11 index = 28
active count = 11 index = 29
active count = 11 index = 30
active count = 11 index = 31
active count = 11 index = 32
active count = 11 index = 33
active count = 11 index = 34
active count = 11 index = 35
active count = 11 index = 36
active count = 11 index = 37
active count = 11 index = 38
active count = 11 index = 39
active count = 11 index = 40
active count = 11 index = 41
active count = 11 index = 42
active count = 11 index = 43
active count = 11 index = 44
active count = 11 index = 45
active count = 11 index = 46
active count = 11 index = 47
active count = 11 index = 48
active count = 10 index = 49
從列印消息來看開始線程數在增加,後來穩定,可以修改休眠時間,休眠時間越短創建的線程數就越多,因為前面的還沒執行完,線程池中沒有可以執行的就需要創建;如果把休眠時間加大,創建的線程數就會少
2.newFixedThreadPool 根據傳入的參數創建線程數目
/**
* 定長線程池
*/
public static void Function2() {
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 30; i++) {
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("index = " + index
+ " thread count = " + Thread.activeCount());
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
3.newScheledThreadPool
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 定長線程池,可做延時
*/
public static void Function3() {
ScheledExecutorService executorService = Executors
.newScheledThreadPool(5);
executorService.schele(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds" + " thread count = "
+ Thread.activeCount());
}
}, 3, TimeUnit.SECONDS);
}
/**
* 定期執行,可以用來做定時器
*/
public static void Function4() {
ScheledExecutorService executorService = Executors
.newScheledThreadPool(3);
executorService.scheleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out
.println("delay 1 seconds, and excute every 3 seconds"
+ " thread count = " + Thread.activeCount());
}
}, 1, 3, TimeUnit.SECONDS);
}
列印結果
?
1
2
3
4
5
6
7
8
9
delay 1 seconds, and excute every 3 seconds thread count = 2
delay 1 seconds, and excute every 3 seconds thread count = 3
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
delay 1 seconds, and excute every 3 seconds thread count = 4
4.newSingleThreadExecutor這個最簡單
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 單例線程
*/
public static void Function5() {
ExecutorService singleThreadExecutor = Executors
.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("index = " + index
+ " thread count = " + Thread.activeCount());
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
列印結果:
?
1
2
3
4
5
index = 0 thread count = 2
index = 1 thread count = 2
index = 2 thread count = 2
index = 3 thread count = 2
index = 4 thread count = 2
6. android handler queue.next怎麼實現的
Android的消息機制其實在android的開發過程中指的也就是Handler的運行機制,這也就引出了android中常見的面試問題:
簡述Handler、Looper、MessageQueue的含義,以及它們之間的關系
簡述Handler的運行機制
說明Handler、Looper以及Message之間的關系
7. android中主線程會創建消息隊列嗎
一、Handler的定義: Handler主要接收子線程發送的數據, 並用此數據配合主線程更新UI,用來跟UI主線程交互用。比如可以用handler發送一個message,然後在handler的線程中來接收、處理該消息,以避免直接在UI主線程中處理事務導致影響UI主線程的其他處理工作,Android提供了Handler作為主線程和子線程的紐帶;也可以將handler對象傳給其他進程,以便在其他進程中通過handler給你發送事件;還可以通過handler的延時發送message,可以延時處理一些事務的處理。 通常情況下,當應用程序啟動時,Android首先會開啟一個主線程 (也就是UI線程) , 主線程為管理界面中的UI控制項,進行事件分發。如果此時需要一個耗時的操作,例如:聯網讀取數據,或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現假死現象,如果5秒鍾還沒有完成的話,會收到Android系統的一個錯誤提示"強制關閉". 這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,但是當子線程中有涉及到操作UI的操作時,就會對主線程產生危險,也就是說,更新UI只能在主線程中更新,在子線程中操作是危險的. 這個時候,Handler就出現了來解決這個復雜的問題,由於Handler運行在主線程中(UI線程中),它與子線程可以通過Message對象來傳遞數據,這個時候,Handler就承擔著接受子線程傳過來的(子線程用sedMessage()方法傳遞)Message對象,(裡麵包含數據), 把這些消息放入主線程隊列中,配合主線程進行更新UI。 二、Handler一些特點 handler可以分發Message對象和Runnable對象到主線程中, 每個Handler實例,都會綁定到創建他的線程中(一般是位於主線程), 也就是說Handler對象初始化後,就默認與對它初始化的進程的消息隊列綁定,因此可以利用Handler所包含的消息隊列,制定一些操作的順序。 三、Handler中分發消息的一些方法 post(Runnable) postAtTime(Runnable,long) postDelayed(Runnable long) post類方法允許你排列一個Runnable對象到主線程隊列中 sendEmptyMessage(int) sendMessage(Message) sendMessageAtTime(Message,long) sendMessageDelayed(Message,long) sendMessage類方法, 允許你安排一個帶數據的Message對象到隊列中,等待更新. 四、應用實例: 1,傳遞Message。用於接受子線程發送的數據, 並用此數據配合主線程更新UI。 在Android中,對於UI的操作通常需要放在主線程中進行操作。如果在子線程中有關於UI的操作,那麼就需要把數據消息作為一個Message對象發送到消息隊列中,然後,用Handler中的handlerMessge方法處理傳過來的數據信息,並操作UI。類sendMessage(Message msg)方法實現發送消息的操作。 在初始化Handler對象時重寫的handleMessage方法來接收Messgae並進行相關操作。 2,傳遞Runnable對象。用於通過Handler綁定的消息隊列,安排不同操作的執行順序。 Handler對象在進行初始化的時候,會默認的自動綁定消息隊列。利用類post方法,可以將Runnable對象發送到消息隊列中,按照隊列的機制按順序執行不同的Runnable對象中的run方法。 另外,Android的CPU分配的最小單元是線程,Handler一般是在某個線程里創建的,因而Handler和Thread就是相互綁定的,一一對應。而Runnable是一個介面,Thread是Runnable的子類。所以說,他倆都算一個進程。 視頻教程中的例子: 1. public class HandlerActivity extends Activity { 2. 3. //聲明兩個按鈕控制項 4. private Button startButton = null; 5. private Button endButton = null; 6. @Override 7. public void onCreate(Bundle savedInstanceState) { 8. super.onCreate(savedInstanceState); 9. setContentView(R.layout.main); 10. //根據控制項的ID得到代表控制項的對象,並為這兩個按鈕設置相應的監聽器 11. startButton = (Button)findViewById(R.id.startButton); 12. startButton.setOnClickListener(new StartButtonListener()); 13. endButton = (Button)findViewById(R.id.endButton); 14. endButton.setOnClickListener(new EndButtonListener()); 15. 16. } 17. class StartButtonListener implements OnClickListener{ 18. 19. @Override 20. public void onClick(View v) { 21. //調用Handler的post方法,將要執行的線程對象添加到隊列當中 22. handler.post(updateThread); 23. } 24. 25. } 26. 27. class EndButtonListener implements OnClickListener{ 28. 29. @Override 30. public void onClick(View v) { 31. handler.removeCallbacks(updateThread); 32. } 33. 34. } 35. //創建一個Handler對象 36. Handler handler = new Handler(); 37. //將要執行的操作寫在線程對象的run方法當中 38. Runnable updateThread = new Runnable(){ 39. 40. @Override 41. public void run() { 42. System.out.println("UpdateThread"); 43. //在run方法內部,執行postDelayed或者是post方法 44. handler.postDelayed(updateThread, 3000); 45. } 46. 47. }; 48. } 程序的運行結果就是每隔3秒鍾,就會在控制台列印一行UpdateTread。這是因為實現了Runnable介面的updateThread對象進入了空的消息隊列即被立即執行run方法,而在run方法的內部,又在3000ms之後將其再次發送進入消息隊列中。 3, Handler和多線程 post方法雖然發送的是一個實現了Runnable介面的類對象,但是它並非創建了一個新線程,而是執行了該對象中的run方法。也就是說,整個run中的操作和主線程處於同一個線程。 這樣對於那些簡單的操作,似乎並不會影響。但是對於耗時較長的操作,就會出現「假死」。為了解決這個問題,就需要使得handler綁定到一個新開啟線程的消息隊列上,在這個處於另外線程的上的消息隊列中處理傳過來的Runnable對象和消息。 1. public class HandlerTest2 extends Activity { 2. 3. @Override 4. protected void onCreate(Bundle savedInstanceState) { 5. // TODO Auto-generated method stub 6. super.onCreate(savedInstanceState); 7. setContentView(R.layout.main); 8. //列印了當前線程的ID 9. System.out.println("Activity-->" + Thread.currentThread().getId()); 10. //生成一個HandlerThread對象 11. HandlerThread handlerThread = new HandlerThread("handler_thread"); 12. //在使用HandlerThread的getLooper()方法之前,必須先調用該類的start(),同時開啟一個新線程; 13. handlerThread.start(); 14. //將由HandlerThread獲取的Looper傳遞給Handler對象,即由處於另外線程的Looper代替handler初始化時默認綁定的消息隊列來處理消息。 15. // HandlerThread顧名思義就是可以處理消息循環的線程,它是一個擁有Looper的線程 16. ,可以處理消息循環; 其實與其說Handler和一個線程綁定,倒不如說Handler和Looper是 17. 一一對應的。 18. MyHandler myHandler = new MyHandler(handlerThread.getLooper()); 19. Message msg = myHandler.obtainMessage(); 20. //將msg發送到目標對象,所謂的目標對象,就是生成該msg對象的handler對象 21. Bundle b = new Bundle(); 22. b.putInt("age", 20); 23. b.putString("name", "Jhon"); 24. msg.setData(b); 25. msg.sendToTarget(); //將msg發送到myHandler 26. } 27. 28. //定義類 29. class MyHandler extends Handler{ 30. public MyHandler(){ 31. 32. } 33. 34. public MyHandler(Looper looper){ 35. super(looper); 36. } 37. @Override 38. public void handleMessage(Message msg) { 39. Bundle b = msg.getData(); 40. int age = b.getInt("age"); 41. String name = b.getString("name"); 42. System.out.println("age is " + age + ", name is" + name); 43. System.out.println("Handler--->" + Thread.currentThread().getId()); 44. System.out.println("handlerMessage"); 45. } 46. } 47. } 這樣,當使用sendMessage方法傳遞消息或者使用post方法傳遞Runnable對象時,就會把它們傳遞到與handler對象綁定的處於另外一個線程的消息隊列中,它們將在另外的消息隊列中被處理。而主線程還會在發送操作完成時候繼續進行,不會影響當前的操作。 這里需要注意,這里用到的多線程並非由Runnable對象開啟的,而是ThreadHandler對象開啟的。Runnable對象只是作為一個封裝了操作的對象被傳遞,並未產生新線程。 另外再強調一遍,在UI線程(主線程)中: mHandler=new Handler(); mHandler.post(new Runnable(){ void run(){ //執行代碼.. } }); 這個線程其實是在UI線程之內運行的,並沒有新建線程。 常見的新建線程的方法是: Thread thread = new Thread(); thread.start(); HandlerThread thread = new HandlerThread("string"); thread.start();
8. android里的所有事件都是基於消息隊列的嗎
Android廣播分為兩個方面:廣播發送者和廣播接收者,通常情況下,BroadcastReceiver指的就是廣播接收者(廣播接收器)。廣播作為Android組件間的通信方式,可以使用的場景如下:1.同一app內部的同一組件內的消息通信(單個或多個線程之間)。2.同一app內部的不同組件之間的消息通信(單個進程)。3.同一app具有多個進程的不同組件之間的消息通信。4.不同app之間的組件之間消息通信。5.Android系統在特定情況下與App之間的消息通信。從實現原理看上,Android中的廣播使用了觀察者模式,基於消息的發布/訂閱事件模型。因此,從實現的角度來看,Android中的廣播將廣播的發送者和接受者極大程度上解耦,使得系統能夠方便集成,更易擴展。具體實現流程要點粗略概括如下:1.廣播接收者BroadcastReceiver通過Binder機制向AMS(Activity Manager Service)進行注冊;2.廣播發送者通過binder機制向AMS發送廣播;3.AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadcastReceiver(一般情況下是Activity)相應的消息循環隊列中;4.消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。 對於不同的廣播類型,以及不同的BroadcastReceiver注冊方式,具體實現上會有不同。但總體流程大致如上。
9. 誰能幫我詳細解釋一下Android MediaCodec類中queueInputBuffer這個方法
queueInputBuffer和dequeueInputBuffer是一對方法,兩個要在一起使用哦。
首先,這一對函數的應用場合是對輸入的數據流進行編碼或者解碼處理的時候,你會通過各種方法獲得一個ByteBuffer的數組,這些數據就是准備處理的數據。
你要通過自己的方法找到你要處理的部分,然後調用dequeueInputBuffer方法提取出要處理的部分(也就是一個ByteBuffer數據流),把這一部分放到緩存區。
接下來就是你自己對於這個數據流的處理了。
然後在處理完畢之後,一定要調用queueInputBuffer把這個ByteBuffer放回到隊列中,這樣才能正確釋放緩存區。
對於輸出的數據流,同樣也有一對這樣的函數,叫做queueOutputBuffer和dequeueOutputBuffer,作用類似哦。
希望採納~w
10. Andriod是不是每個線程都有消息隊列
你好
很高興為你解答
答案是:
熟悉Windows編程的朋友可能知道Windows程序是消息驅動的,並且有全局的消息循環系統。而Android應用程序也是消息驅動的,按道 理來說也應該提供消息循環機制。實際上谷歌參考了Windows的消息循環機制,也在Android系統中實現了消息循環機制。Android通過 Looper、Handler來實現消息循環機制,Android消息循環是針對線程的(每個線程都可以有自己的消息隊列和消息循環)。本文深入介紹一下 Android消息處理系統原理。
前面提到Android系統的消息隊列和消息循環都是針對具體線程的,一個線程可以存在(當然也可以不存在)一個消息隊列和一個消息循環 (Looper),特定線程的消息只能分發給本線程,不能進行跨線程,跨進程通訊。但是創建的工作線程默認是沒有消息循環和消息隊列的,如果想讓該線程具 有消息隊列和消息循環,需要在線程中首先調用Looper.prepare()來創建消息隊列,然後調用Looper.loop()進入消息循環。
滿意請採納,謝謝