# 面試看這就夠了 吧 ## Reference Type v.s. Value Type **Value Type 基本型態**: byte、short、int、long、float、double、boolean和char 宣告變數時配置記憶體位置,同時將實際值賦予變數 **Reference Type 參考型態**: 內建物件之陣列(矩陣)、字串,與自行設計之建構物件 這三種變數的值存放的是參考而非實值,也就是存放指向物件的位址。 宣告變數時配置記憶體位置,值為一段位置,要到heap區找實際值(實例資料會儲存在 Heap 中,Stack 內的變數值為實例在 Heap 中的記憶體位址) 資料的實值型別及參考型別: https://tianchyi1955.pixnet.net/blog/post/101762587?pixfrom=related JVM 的 Stack 和 Heap: https://blog.marksylee.com/2016/09/14/java-interview-02-jvm-stack-heap/ ![](https://i.imgur.com/0d12xSK.png) ## Thread & Handler ### Why & What Thread & Handler 當使用者啟動 APP 時,Android 會建立自己的 Linux process ,伴隨著這個 process,系統建立一個專門執行 APP 的 Thread (UI Thread),這個 Thread 就是我們俗稱的 Main Thread,它本身就是一個 Handler Thread。 Android 處理程式常須執行在多執行緒環境中,UI Thread被lock超過5秒以上會ANR,使用Handler 解決此問題。 ![](https://i.imgur.com/BJaIJV8.png) ### Key words 相關 class **Runnable** : 工作,任務,run() **Handler** : 不同 Thread 之間的溝通工具,提供 callback function 給其它 Thread 作執行,發送並處理與該 Thread 有關的 Message 和 Runnable **Message** : 用來辨識要處理的 Runnable **MessageQueue** : 緩衝,讓 Message 暫存 **Looper** : Looper取出訊息,處理 Message,一個線呈一個 Looper,處理完將 Message發送給 Handler **Thread** : 處理程式 > #### **共同目標 : 讓程式能夠丟到其他 Thread 執行** ### Looper 1. Looper 提供了 Looper.prepare() 方法來創建 Looper 2. ThreadLocal 來實現與當前線程的綁定 3. Looper.loop() 則會開始不斷嘗試從 MessageQueue 中獲取 Message , 並分發給對應的 Handler ### Message ```kotlin= val message = Message() message.what = 1 message.arg1 = 123 //message.data mainHandler.sendMessage(message) . . // handler 內部 when (msg.what){ 1 -> { textView.text = "下載完成" } } ``` ### Android 環境內,Thread 分兩種: **單次Thread** : 做完即關閉 ```java= Thread t1 = new Thread(r1); //r1為Runnable (工作) t1.start(); //start即開始工作,做完即結束 ``` **常駐Thread** : HandlerThread,做完idle(閒置) ```java= HandlerThread handlerThread = new HandlerThread("HandlerThread"); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()) handler.post(r1) handler.sendMessage(message) ...... handlerThread.quit() //start待命,兩種形式post or sendMessage 給工作,做完idle,直到quit()才結束 ``` **流程圖:** ![](https://i.imgur.com/wCbo8i1.png) HandlerThread run 方法內建立looper,loopr建立handler,handler發、處理信息 Handler 非同步更新UI,做執行續之間的通訊(子與Main) HandlerThread 使用方式: //參數:線呈名稱 mHandlerThread = new HandlerThread("HandlerThread"); handlerThread.start(); 結束:釋放記憶體 mHandlerThread.quit() 建立handler時會先檢查該thread有無looper,沒有則throw exception,主線呈會自動建立looper所以不會拋錯 > 在創建 Handler 之前一定需要先創建 Looper ### Thread vs Memory Leak ![](https://i.imgur.com/4UiMr2o.png) 非靜態的內部類別持有外部對象的引用,而Handler又由於Message的處理可能會常駐於process裡,導致雖然所在的Activity或Service在Destory後無法及時被GC回收,導致Memory Leak,因此比較建議使用static的寫法 > private Handler mUI_Handler = new Handler(); > 會建立一個基於Main Thread (UI Thread)的Handler 原文網址:https://kknews.cc/code/4k9abnx.html https://codertw.com/android-%E9%96%8B%E7%99%BC/352565/ Handler版本改變 https://shoewann0402.github.io/2020/03/09/android-R-about-handler-change/ HT vs T 多looper https://milochen.wordpress.com/2011/03/25/understanding-android-os-src-looperhandler-message-messagequeue/ ## Program Process Thread * #### Program (程式) Program = Code * #### Process ( 程序、進程 ) Process = 執行 APP 後,CPU 執行且 load 到記憶體的 Program * #### Thread (執行緒、線程 ) Thread = Process 就是 Thread 的容器,一個 Process 中會有很多個 Thread ,每一個 Thread 負責某一項功能。