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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android r.java 原理,深入理解Android消息处理系统原理

發(fā)布時間:2023/12/20 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android r.java 原理,深入理解Android消息处理系统原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Android應(yīng)用程序也是消息驅(qū)動的,按道理來說也應(yīng)該提供消息循環(huán)機制。實際上谷歌參考了Windows的消息循環(huán)機制,也在Android系統(tǒng)中實現(xiàn)了消息循環(huán)機制。

Android通過Looper、Handler來實現(xiàn)消息循環(huán)機制,Android消息循環(huán)是針對線程的(每個線程都可以有自己的消息隊列和消息循環(huán))。

本文深入介紹一下Android消息處理系統(tǒng)原理。

Android系統(tǒng)中Looper負責管理線程的消息隊列和消息循環(huán),具體實現(xiàn)請參考Looper的源碼。 可以通過Loop.myLooper()得到當前線程的Looper對象,通過Loop.getMainLooper()可以獲得當前進程的主線程的Looper對象。

前面提到Android系統(tǒng)的消息隊列和消息循環(huán)都是針對具體線程的,一個線程可以存在(當然也可以不存在)一個消息隊列 和一個消息循環(huán)(Looper),特定線程的消息只能分發(fā)給本線程,不能進行跨線程,跨進程通訊。但是創(chuàng)建的工作線程默認是沒有消息循環(huán)和消息隊列的,如果想讓該線程具有消息隊列和消息循環(huán),需要在線程中首先調(diào)用Looper.prepare()來創(chuàng)建消息隊列,然后調(diào)用Looper.loop()進入消息循環(huán)。如下例所示:

classLooperThreadextendsThread?{

publicHandler?mHandler;

publicvoidrun()?{

Looper.prepare();

mHandler?=newHandler()?{

publicvoidhandleMessage(Message?msg)?{

//?process?incoming?messages?here

}

};

Looper.loop();

}

}

這樣你的線程就具有了消息處理機制了,在Handler中進行消息處理。

Activity是一個UI線程,運行于主線程中,Android系統(tǒng)在啟動的時候會為Activity創(chuàng)建一個消息隊列和消息循環(huán)(Looper)。詳細實現(xiàn)請參考ActivityThread.java文件。

Handler的作用是把消息加入特定的(Looper)消息隊列中,并分發(fā)和處理該消息隊列中的消息。構(gòu)造Handler的時候可以指定一個Looper對象,如果不指定則利用當前線程的Looper創(chuàng)建。詳細實現(xiàn)請參考Looper的源碼。

Activity、Looper、Handler的關(guān)系如下圖所示:

一個Activity中可以創(chuàng)建多個工作線程或者其他的組件,如果這些線程或者組件把他們的消息放入Activity的主線程消息隊列,那么該消息就會在 主線程中處理了。因為主線程一般負責界面的更新操作,并且Android系統(tǒng)中的weget不是線程安全的,所以這種方式可以很好的實現(xiàn)Android界 面更新。在Android系統(tǒng)中這種方式有著廣泛的運用。

那么另外一個線程怎樣把消息放入主線程的消息隊列呢?

答案是通過Handle對象,只要Handler對象以主線程的Looper創(chuàng)建,那么調(diào)用 Handler的sendMessage等接口,將會把消息放入隊列都將是放入主線程的消息隊列。并且將會在Handler主線程中調(diào)用該handler 的handleMessage接口來處理消息。

這里面涉及到線程同步問題,請先參考如下例子來理解Handler對象的線程模型:

1、首先創(chuàng)建MyHandler工程。

2、在MyHandler.java中加入如下的代碼:

packagecom.simon;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.os.Message;

importandroid.util.Log;

importandroid.os.Handler;

publicclassMyHandlerextendsActivity?{

staticfinalString?TAG?="Handler";

Handler?h?=newHandler(){

publicvoidhandleMessage?(Message?msg)

{

switch(msg.what)

{

caseHANDLER_TEST:

Log.d(TAG,"The?handler?thread?id?=?"+?Thread.currentThread().getId()?+"\n");

break;

}

}

};

staticfinalintHANDLER_TEST?=1;

/**?Called?when?the?activity?is?first?created.?*/

@Override

publicvoidonCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

Log.d(TAG,"The?main?thread?id?=?"+?Thread.currentThread().getId()?+"\n");

newmyThread().start();

setContentView(R.layout.main);

}

classmyThreadextendsThread

{

publicvoidrun()

{

Message?msg?=newMessage();

msg.what?=?HANDLER_TEST;

h.sendMessage(msg);

Log.d(TAG,"The?worker?thread?id?=?"+?Thread.currentThread().getId()?+"\n");

}

}

}

在這個例子中我們主要是打印,這種處理機制各個模塊的所處的線程情況。如下是我的機器運行結(jié)果:

09-10 23:40:51.478: DEBUG/Handler(302): The main thread id = 1 09-10 23:40:51.569: DEBUG/Handler(302): The worker thread id = 8 09-10 23:40:52.128: DEBUG/Handler(302): The handler thread id = 1

我們可以看出消息處理是在主線程中處理的,在消息處理函數(shù)中可以安全的調(diào)用主線程中的任何資源,包括刷新界面。工作線程和主線程運行在不同的線程中,所以必須要注意這兩個線程間的競爭關(guān)系。

上例中,你可能注意到在工作線程中訪問了主線程handler對象,并在調(diào)用handler的對象向消息隊列加入了一個消息。這個過程中會不會出現(xiàn)消息隊 列數(shù)據(jù)不一致問題呢?答案是handler對象不會出問題,因為handler對象管理的Looper對象是線程安全的,不管是加入消息到消息隊列和從隊 列讀出消息都是有同步對象保護的,具體請參考Looper.java文件。上例中沒有修改handler對象,所以handler對象不可能會出現(xiàn)數(shù)據(jù)不 一致的問題。

通過上面的分析,我們可以得出如下結(jié)論:

1、如果通過工作線程刷新界面,推薦使用handler對象來實現(xiàn)。

2、注意工作線程和主線程之間的競爭關(guān)系。推薦handler對象在主線程中構(gòu)造完成(并且啟動工作線程之后不要再修改之,否則會出現(xiàn)數(shù)據(jù)不一致),然后在工作線程中可以放心的調(diào)用發(fā)送消息SendMessage等接口。

3、除了2所述的hanlder對象之外的任何主線程的成員變量如果在工作線程中調(diào)用,仔細考慮線程同步問題。如果有必要需要加入同步對象保護該變量。

4、handler對象的handleMessage接口將會在主線程中調(diào)用。在這個函數(shù)可以放心的調(diào)用主線程中任何變量和函數(shù),進而完成更新UI的任務(wù)。

5、Android很多API也利用Handler這種線程特性,作為一種回調(diào)函數(shù)的變種,來通知調(diào)用者。這樣Android框架就可以在其線程中將消息發(fā)送到調(diào)用者的線程消息隊列之中,不用擔心線程同步的問題。

深入理解Android消息處理機制對于應(yīng)用程序開發(fā)非常重要,也可以讓你對線程同步有更加深刻的認識。

【編輯推薦】

【責任編輯:小野 TEL:(010)68476606】

總結(jié)

以上是生活随笔為你收集整理的android r.java 原理,深入理解Android消息处理系统原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。