androidhandler方法
❶ Android:在一個非主線程內直接調用UI線程的Handler實例,這樣沒問題嗎
在Android開發中,我們常常遇到線程安全的問題,特別是在子線程和UI線程之間進行交互時。為了保證應用程序的穩定性和用戶體驗,我們不能直接在子線程中更新UI線程中的UI元素。為了解決這個問題,Android提供了一種機制——Handler。
Handler的工作原理是這樣的:當子線程需要更新UI線程中的UI元素時,它會通過發送消息的方式,將需要更新的內容傳遞給UI線程。這些消息會被放入UI線程的消息隊列中,然後由UI線程中的Handler逐個處理。這樣,我們就可以在子線程中執行耗時操作,同時在UI線程中更新UI,從而保證了界面的流暢性。
在Android中,創建多線程的方式主要有兩種:一種是通過繼承Thread類並重寫run方法;另一種是通過實現Runnable介面並實現run方法。無論哪種方式,子線程都無法直接修改UI線程中的UI元素,而Handler正是用來解決這一問題的關鍵。
Handler的主要方法包括post、postAtTime、postDelayed、sendEmptyMessage、sendMessage、sendMessageAtTime、sendMessageDelayed等。這些方法分別用於在主線程中執行Runnable或發送消息。通過這些方法,我們可以靈活地控制消息的發送時機和執行方式。
下面,我們通過一個簡單的例子來說明Handler的使用方法。假設我們需要在主線程中的TextView中顯示10到100之間的隨機數,每隔5秒更新一次,總共更新5次。主要代碼如下:
java
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.post(run);
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
String s = String.valueOf(msg.what);
TextView tv = (TextView)findViewById(R.id.textView);
tv.setText(tv.getText() + " " + s);
}
};
Runnable run = new Runnable(){
@Override
public void run(){
Random r = new Random();
int rnum = r.nextInt((100 - 10) + 1) + 10;
handler.sendEmptyMessage(rnum);
handler.postDelayed(run, 5000);
i++;
if (i==5){
handler.removeCallbacks(run);
}
}
};
通過這個例子,我們可以看到Handler在處理子線程與UI線程之間的交互時的重要作用。在實際開發中,我們可以根據具體需求,靈活地使用Handler的各種方法來實現復雜的線程交互邏輯。
❷ android中Handler的post方法的作用是什麼
在工作線程中執行耗時任務,當任務完成時,會返回UI線程,一般是更新UI。這時有兩種方法可以達到目的。
一種是handler.sendMessage。發一個消息,再根據消息,執行相關任務代碼。
另一種是handler.post(r)。r是要執行的任務代碼。意思就是說r的代碼實際是在UI線程執行的。可以寫更新UI的代碼。
(2)androidhandler方法擴展閱讀
一個APK文件結構為:
1、META-INF (註:Jar文件中常可以看到);
2、res (註:存放資源文件的目錄) ;
3、AndroidManifest.xml (註:程序全局配置文件) ;
4、classes.dex (註:Dalvik位元組碼);
5、resources.arsc (註:編譯後的二進制資源文件)。
Android在運行一個程序時首先需要UnZip,然後類似Symbian那樣直接執行安裝,和Windows Mobile中的PE文件有區別,這樣做對於程序的保密性和可靠性不是很高,通過dexmp命令可以反編譯,但這樣做符合發展規律,微軟的 Windows Gadgets或者說WPF也採用了這種構架方式。
在Android平台中dalvik vm的執行文件被打包為apk格式,最終運行時載入器會解壓然後獲取編譯後androidmanifest.xml文件中的permission分支相關的安全訪問,但仍然存在很多安全限制,如果你將apk文件傳到/system/app文件夾下會發現執行是不受限制的。
參考資料來源:網路-Android
❸ Android——消息分發機制
什麼是 Handler 機制 ?
Handler 機制是 Android 中用於 線程間通信 的一套通信機制。
為什麼是 Handler ?Handler 機制為什麼被那麼多次的提及 ?
從Android4.0開始,Android 中網路請求強制不允許在主線程中操作,而更新UI的操作則不允許在子線程中執行。當在子線程中執行網路請求,拿到伺服器返回的數據之後,要更新UI。由於系統的要求,勢必會產生一種矛盾:數據在子線程,更新UI要在主線程。此時我們必須要把數據返回到主線程中才行,Handler機制應運而生。
Android 中針對耗時的操作,放在主線程操作,輕者會造成 UI 卡頓,重則會直接無響應,造成 Force Close。同時在 Android 3.0 以後,禁止在主線程進行網路請求。
針對耗時或者網路操作,那就不能在主線程進行直接操作了,需要放在子線程或者是工作線程中進行操作,操作完成以後,再更新主線程即 UI 線程。這里就涉及到一個問題了,在子線程執行完成以後,怎麼能更新到主線程即 UI 線程呢,針對以上問題,就需要用到 Android 的消息機制了,即: Handler, Message, MessageQueue, Looper 全家桶
Handler機制中最重要的四個對象
Handler的構造方法:
Looper :
Handler的使用:
MessageQueue:
Looper.loop()
Handler.dispatchMessage()
handler導致activity內存泄露的原因:
handler發送的消息在當前handler的消息隊列中,如果此時activity finish掉了,那麼消息隊列的消息依舊會由handler進行處理,若此時handler聲明為內部類(非靜態內部類),我們知道內部類天然持有外部類的實例引用,這樣在GC垃圾回收機制進行回收時發現這個Activity居然還有其他引用存在,因而就不會去回收這個Activity,進而導致activity泄露。
假如在子線程執行了耗時操作,這時用戶操作進入了其他的 acitvity, 那麼 MainActivity 就會被內存回收的,但是這個時候發現 Handler 還在引用著 MainActivity,內存無法及時回收,造成內存泄漏。
Handler 防止內存泄漏常見方法:
為什麼通過 Handler 可以把子線程的結果通知或者攜帶給 UI 線程 ?
這里的 Handler 指的是主線程的 Handler ,同時與 Handler 配套的 Looper , MessageQueue 是在 UI 線程初始化的,所以在子線程中調用 Handler 發送消息可以更新 UI 線程。
Looper 在 UI 線程源碼, 在 ActivityThread 類: