【移動應用開發(fā)技術】Android中如何實現異步消息機制_第1頁
【移動應用開發(fā)技術】Android中如何實現異步消息機制_第2頁
【移動應用開發(fā)技術】Android中如何實現異步消息機制_第3頁
【移動應用開發(fā)技術】Android中如何實現異步消息機制_第4頁
【移動應用開發(fā)技術】Android中如何實現異步消息機制_第5頁
免費預覽已結束,剩余2頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

【移動應用開發(fā)技術】Android中如何實現異步消息機制

這篇文章給大家介紹Android中如何實現異步消息機制,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。Android中的異步消息機制分為四個部分:Message、Handler、MessageQueue和Looper。其中,Message是線程之間傳遞的消息,其what、arg1、arg2字段可以攜帶整型數據,obj字段可以攜帶一個Object對象。Handler是處理者,主要用于發(fā)送消息和處理消息。發(fā)送消息的方法是sendMessage;處理消息的方法是handleMessage(),Message字段攜帶的信息在該方法中用作判別。MessageQueue是消息隊列,存放所有Handler發(fā)送的消息。Looper是消息隊列的“管家”,將消息從消息隊列中一條條取出,并分派到Handler的handleMessage()方法中。異步消息處理的流程為:①首先,需要在主線程中創(chuàng)建一個Handler對象,并重寫handleMessage()方法。②當子線程處理完耗時操作,需要將處理結果反饋到UI中時,先創(chuàng)建一個Message對象,并讓其what字段攜帶一個int值,然后通過Handler對象發(fā)送出去。③之后該消息會被添加到MessageQueue中等待被處理,而Looper會一直嘗試從MessageQueue中取出待處理消息,最后分發(fā)回Handler對象中的handleMessage()方法中。由于Handler對象是在主線程中創(chuàng)建的,所以可以在handleMessage()方法中安心地進行UI操作。通過一個例子來驗證一下:活動MainActivity中有一個按鈕和一個TextView。TextView初始化顯示“HelloWorld!”,之后點擊按鈕,進行耗時操作;耗時操作結束后,TextView顯示“Nicetomeetyou”。根據以上的分析,我無比自然地寫出了以下代碼:package

com.shaking.androidthreadtest;

import

android.os.Handler;

import

android.os.Message;

import

android.support.v7.app.AppCompatActivity;

import

android.os.Bundle;

import

android.view.View;

import

android.widget.Button;

import

android.widget.TextView;

public

class

MainActivity

extends

AppCompatActivity

implements

View.OnClickListener{

private

static

final

int

UPDATE_TEXT=1;

private

String

data;

private

TextView

textView;

private

Handler

handler=new

Handler(){

@Override

public

void

handleMessage(Message

msg)

{

switch

(msg.what){

case

UPDATE_TEXT:

textView.setText(data);

}

}

};

@Override

protected

void

onCreate(Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main_layout);

Button

button=findViewById(R.id.button);

textView=findViewById(R.id.text_view);

button.setOnClickListener(this);

}

@Override

public

void

onClick(View

view)

{

new

Thread(new

Runnable()

{

@Override

public

void

run()

{

//假設此處進行了耗時操作,最終得到結果字符串data

data="Nice

to

meet

you";

Message

message=new

Message();

message.what=UPDATE_TEXT;

handler.sendMessage(message);

}

}).start();

}

}首先,這么寫,是肯定沒有錯誤的!程序也可以正常運行。但是IDE給出了警告:“ThisHandlerclassshouldbestaticorleaksmightoccur”。這個警告的意思是:我們使用Handler這個類時,應該將其聲明為靜態(tài),否則會導致內存泄露。那么,為什么會發(fā)生內存泄露呢?原因是:第一:當我們通過Handler對象的sendMessage()方法發(fā)送一個Message對象時,該Message對象持有對該Handler對象的引用(正是依靠這個引用,Looper在消息隊列中取出該Message對象后,才能準確地將該Message對象分派回該Handler對象?。?。第二,我們在主線程中創(chuàng)建Handler對象時,為了重寫其handleMessage()方法,使用了匿名內部類的方式來創(chuàng)建該Handler對象。而匿名內部類和非靜態(tài)內部類都是隱性地持有一個對外部類的引用!所以,該Handler對象持有外部類MainActivity的引用。以上兩個結合在一起,問題就來了:Message對象持有Handler對象引用,Handler對象持有MainActivity的引用。所以,MainActivity該活動永遠無法被內存回收,直到Message被回收為止!如果Message對象在子線程中被發(fā)送至消息隊列,然后一直沒有被處理,該活動所在的主線程也會一直掛著,而不會被內存回收。所以,會導致內存泄露。知道了原因,那么解決方法是什么?其實之前的警告,已經給出了解決方案。那就是通過靜態(tài)內部類的方式創(chuàng)建Handler對象,因為靜態(tài)內部類不會持有對外部類對象的引用。這時候,我又自然而然地創(chuàng)建一個靜態(tài)內部類,繼承自Handler類,然后重寫其handleMessage方法。private

static

class

MyHandler

extends

Handler{

@Override

public

void

handleMessage(Message

msg)

{

}

}但是,此處又出現了一個問題!如果我不持有對外部類的引用了,那么我怎么使用外部類的方法和對象?畢竟我是要在handleMessage()方法中進行UI操作的。對于這種使用了靜態(tài)內部類來避免內存泄露,同時又需要調用外部類的方法的情況:可以使用弱引用!即我們在該內部類中聲明一個對外部類對象的弱引用。這樣即可以調用外部類的方法,又不會導致內存泄露。具體修改后的代碼,如下:package

com.shaking.androidthreadtest;

import

android.os.Handler;

import

android.os.Message;

import

android.support.v7.app.AppCompatActivity;

import

android.os.Bundle;

import

android.view.View;

import

android.widget.Button;

import

android.widget.TextView;

import

java.lang.ref.WeakReference;

public

class

MainActivity

extends

AppCompatActivity

implements

View.OnClickListener{

private

static

final

int

UPDATE_TEXT=1;

private

String

data;

private

TextView

textView;

private

static

class

MyHandler

extends

Handler{

//使該內部類持有對外部類的弱引用

private

WeakReference<MainActivity>

weakReference;

//構造器中完成弱引用初始化

MyHandler(MainActivity

activity){

weakReference=new

WeakReference<>(activity);

}

@Override

public

void

handleMessage(Message

msg)

{

//通過弱引用的get()方法獲得外部類對象的引用

MainActivity

activity=weakReference.get();

activity.textView.setText(activity.data);

}

}

//創(chuàng)建Handler對象

private

MyHandler

handler=new

MyHandler(this);

@Override

protected

void

onCreate(Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main_layout);

Button

button=findViewById(R.id.button);

textView=findViewById(R.id.text_view);

button.setOnClickListener(this);

}

@Override

public

void

onClick(View

view)

{

new

Thread(new

Runnable()

{

@Override

public

void

run()

{

//假設此處進行了耗時操作,最終得到結果

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論