下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發(fā)技術】淺析Android中的消息機制
在分析Android消息機制之前,我們先來看一段代碼:public
class
MainActivity
extends
Activity
implements
View.OnClickListener
{
private
TextView
stateText;
private
Button
btn;
@Override
public
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stateText
=
(TextView)
findViewById(R.id.tv);
btn
=
(Button)
findViewById(R.id.btn);
btn.setOnClickListener(this);
}
@Override
public
void
onClick(View
v)
{
new
WorkThread().start();
}
//工作線程
private
class
WorkThread
extends
Thread
{
@Override
public
void
run()
{
//處理比較耗時的操作
//處理完成后改變狀態(tài)
stateText.setText("completed");
}
}
}
這段代碼似乎看上去很正常,但是當你運行時就會發(fā)現(xiàn),它會報一個致命性的異常:ERROR/AndroidRuntime(421):
FATAL
EXCEPTION:
Thread-8ERROR/AndroidRuntime(421):
android.view.ViewRoot$CalledFromWrongThreadException:Only
the
original
thread
that
created
a
view
hierarchy
can
touch
its
views.
到底是怎么回事呢?原因在于,Android系統(tǒng)中的視圖組件并不是線程安全的,如果要更新視圖,必須在主線程中更新,不可以在子線程中執(zhí)行更新的操作。
既然這樣,我們就在子線程中通知主線程,讓主線程做更新操作吧。那么,我們?nèi)绾瓮ㄖ骶€程呢?我們需要使用到Handler對象。
我們稍微修改一下上面的代碼:public
class
MainActivity
extends
Activity
implements
View.OnClickListener
{
private
static
final
int
COMPLETED
=
0;
private
TextView
stateText;
private
Button
btn;
private
Handler
handler
=
new
Handler()
{
@Override
public
void
handleMessage(Message
msg)
{
if
(msg.what
==
COMPLETED)
{
stateText.setText("completed");
}
}
};
@Override
public
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stateText
=
(TextView)
findViewById(R.id.tv);
btn
=
(Button)
findViewById(R.id.btn);
btn.setOnClickListener(this);
}
@Override
public
void
onClick(View
v)
{
new
WorkThread().start();
}
//工作線程
private
class
WorkThread
extends
Thread
{
@Override
public
void
run()
{
//處理比較耗時的操作
//處理完成后給handler發(fā)送消息
Message
msg
=
new
Message();
msg.what
=
COMPLETED;
handler.sendMessage(msg);
}
}
}
通過上面這種方式,我們就可以解決線程安全的問題,把復雜的任務處理工作交給子線程去完成,然后子線程通過handler對象告知主線程,由主線程更新視圖,這個過程中消息機制起著重要的作用。
下面,我們就來分析一下Android中的消息機制。
熟悉Windows編程的朋友知道Windows程序是消息驅動的,并且有全局的消息循環(huán)系統(tǒng)。Google參考了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)中的Looper負責管理線程的消息隊列和消息循環(huán)。通過Looper.myLooper()得到當前線程的Looper對象,通過Looper.getMainLooper()得到當前進程的主線程的Looper對象。
前面提到,Android的消息隊列和消息循環(huán)都是針對具體線程的,一個線程可以存在一個消息隊列和消息循環(huán),特定線程的消息只能分發(fā)給本線程,不能跨線程和跨進程通訊。但是創(chuàng)建的工作線程默認是沒有消息隊列和消息循環(huán)的,如果想讓工作線程具有消息隊列和消息循環(huán),就需要在線程中先調用Looper.prepare()來創(chuàng)建消息隊列,然后調用Looper.loop()進入消息循環(huán)。下面是我們創(chuàng)建的工作線程:class
WorkThread
extends
Thread
{
public
Handler
mHandler;
public
void
run()
{
Looper.prepare();
mHandler
=
new
Handler()
{
public
void
handleMessage(Message
msg)
{
//
處理收到的消息
}
};
Looper.loop();
}
}
這樣一來,我們創(chuàng)建的工作線程就具有了消息處理機制了。
那么,為什么前邊的示例中,我們怎么沒有看到Looper.prepare()和Looper.loop()的調用呢?原因在于,我們的Activity是一個UI線程,運行在主線程中,Android系統(tǒng)會在Activity啟動時為其創(chuàng)建一個消息隊列和消息循環(huán)。
前面提到最多的是消息隊列(MessageQueue)和消息循環(huán)(Looper),但是我們看到每個消息處理的地方都有Handler的存在,它是做什么的呢?Handler的作用是把消息加入特定的Looper所管理的消息隊列中,并分發(fā)和處理該消息隊列中的消息。構造Handler的時候可以指定一個Looper對象,如果不指定則利用當前線程的Looper對象創(chuàng)建。下面是Handler的兩個構造方法:/**
*
Default
constructor
associates
this
handler
with
the
queue
for
the
*
current
thread.
*
*
If
there
isn't
one,
this
handler
won't
be
able
to
receive
messages.
*/
public
Handler()
{
if
(FIND_POTENTIAL_LEAKS)
{
final
Class<?
extends
Handler>
klass
=
getClass();
if
((klass.isAnonymousClass()
||
klass.isMemberClass()
||
klass.isLocalClass())
&&
(klass.getModifiers()
&
Modifier.STATIC)
==
0)
{
Log.w(TAG,
"The
following
Handler
class
should
be
static
or
leaks
might
occur:
"
+
klass.getCanonicalName());
}
}
mLooper
=
Looper.myLooper();
if
(mLooper
==
null)
{
throw
new
RuntimeException(
"Can't
create
handler
inside
thread
that
has
not
called
Looper.prepare()");
}
mQueue
=
mLooper.mQueue;
mCallback
=
null;
}
/**
*
Use
the
provided
queue
instead
of
the
default
one.
*/
public
Handler(Looper
looper)
{
mLooper
=
looper;
mQueue
=
looper.mQueue;
mCallback
=
null;
}
下面是消息機制中幾個重要成員的關系圖:
/20141107101727367/20141107101737086
一個Activity中可以創(chuàng)建出多個工作線程,如果這些線程把他們消息放入Activity主線程的消息隊列中,那么消息就會在主線程中處理了。因為主線程一般負責視圖組件的更新操作,對于不是線程安全的視圖組件來說,這種方式能夠很好的實現(xiàn)視圖的更新。
那么,子線程如何把消息放入主線程的消息隊列中呢?只要Handler對象以主線程的Looper創(chuàng)建,那么當調用Handler的sendMessage方法,系統(tǒng)就會把消息主線程的消息隊列,并且將會在調用handleMessage方法時處理主線程消息隊列
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《紅景天苷調節(jié)PI3K-Akt-GSK-3β信號通路抑制高糖誘導下視網(wǎng)膜Müller細胞炎癥反應》
- 2024版租賃期滿續(xù)租協(xié)議(含租金調整機制)3篇
- 2024版文化旅游開發(fā)合同
- 2024版國際貨物買賣運輸合同
- 工業(yè)企業(yè)如何構建高效能的工業(yè)互聯(lián)網(wǎng)平臺
- 《幸福人壽住房反向抵押貸款案例分析》
- 2025年中國連鎖餐飲行業(yè)市場全景評估及發(fā)展趨勢研究預測報告
- 火葬場安全生產(chǎn)風險分級管控體系方案
- 《金屬材料多軸疲勞壽命預報模型研究》
- 2024版:智慧城市建設項目實施與運營合同
- 新時期學校德育工作的思路與方法
- 切爾諾貝利核電站事故工程倫理分析
- 分布式計算安全與隱私保護
- 安全防護、文明施工措施項目支出清單
- 社交媒體在人力資源招聘中的角色與利用研究
- 節(jié)日作文指導課件
- 缺點列舉法課件
- 采購付款明細統(tǒng)計表
- 2022年四川省公務員錄用考試《行測》真題及答案
- 尼康D610數(shù)碼單反攝影從入門到精通
- 2023-2024學年安徽省界首市小學語文三年級期末評估試卷詳細參考答案解析
評論
0/150
提交評論