當前位置:首頁 » 安卓系統 » androidwait

androidwait

發布時間: 2025-08-09 05:19:02

⑴ 每個Android 都應必須了解的多線程知識點~

進程是系統調度和資源分配的一個獨立單位。

在Android中,一個應用程序就是一個獨立的集成,應用運行在一個獨立的環境中,可以避免其他應用程序/進程的干擾。當我們啟動一個應用程序時,系統就會創建一個進程(該進程是從Zygote中fork出來的,有獨立的ID),接著為這個進程創建一個主線程,然後就可以運行MainActivity了,應用程序的組件默認都是運行在其進程中。開發者可以通過設置應用的組件的運行進程,在清單文件中給組件設置:android:process = "進程名";可以達到讓組件運行在不同進程中的目的。讓組件運行在不同的進程中,既有好處,也有壞處。我們依次的說明下。

好處:每一個應用程序(也就是每一個進程)都會有一個內存預算,所有運行在這個進程中的程序使用的總內存不能超過這個值,讓組件運行不同的進程中,可以讓主進程可以擁有更多的空間資源。當我們的應用程序比較大,需要的內存資源比較多時(也就是用戶會抱怨應用經常出現OutOfMemory時),可以考慮使用多進程。

壞處:每個進程都會有自己的虛擬機實例,因此讓在進程間共享一些數據變得相對困難,需要採用進程間的通信來實現數據的共享。

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。

在Android中,線程會有那麼幾種狀態:創建、就緒、運行、阻塞、結束。當應用程序有組件在運行時,UI線程是處於運行狀態的。默認情況下,應用的所有組件的操作都是在UI線程里完成的,包括響應用戶的操作(觸摸,點擊等),組件生命周期方法的調用,UI的更新等。因此如果UI線程處理阻塞狀態時(在線程里做一些耗時的操作,如網路連接等),就會不能響應各種操作,如果阻塞時間達到5秒,就會讓程序處於ANR(application not response)狀態。

1.線程作用

減少程序在並發執行時所付出的時空開銷,提高操作系統的並發性能。

2.線程分類

守護線程、非守護線程(用戶線程)

2.1 守護線程

定義:守護用戶線程的線程,即在程序運行時為其他線程提供一種通用服務
常見:如垃圾回收線程
設置方式:thread.setDaemon(true);//設置該線程為守護線程

2.2 非守護線程(用戶線程)

主線程 & 子線程。

2.2.1 主線程(UI線程)

定義:Android系統在程序啟動時會自動啟動一條主線程
作用:處理四大組件與用戶進行交互的事情(如UI、界面交互相關)
因為用戶隨時會與界面發生交互,因此主線程任何時候都必須保持很高的響應速度,所以主線程不允許進行耗時操作,否則會出現ANR。

2.2.2 子線程(工作線程)

定義:手動創建的線程
作用:耗時的操作(網路請求、I/O操作等)

2.3 守護線程與非守護線程的區別和聯系

區別:虛擬機是否已退出,即
a. 當所有用戶線程結束時,因為沒有守護的必要,所以守護線程也會終止,虛擬機也同樣退出
b. 反過來,只要任何用戶線程還在運行,守護線程就不會終止,虛擬機就不會退出

3.線程優先順序

3.1 表示

線程優先順序分為10個級別,分別用Thread類常量表示。

3.2 設置

通過方法setPriority(int grade)進行優先順序設置,默認線程優先順序是5,即 Thread.NORM_PRIORITY。

4.線程狀態

創建狀態:當用 new 操作符創建一個線程的時候

就緒狀態:調用 start 方法,處於就緒狀態的線程並不一定馬上就會執行 run 方法,還需要等待CPU的調度

運行狀態:CPU 開始調度線程,並開始執行 run 方法

阻塞(掛起)狀態:線程的執行過程中由於一些原因進入阻塞狀態,比如:調用 sleep/wait 方法、嘗試去得到一個鎖等

結束(消亡)狀態:run 方法執行完 或者 執行過程中遇到了一個異常

(1)start()和run()的區別

通過調用Thread類的start()方法來啟動一個線程,這時此線程是處於就緒狀態,並沒有運行。調用Thread類調用run()方法來完成其運行操作的,方法run()稱為線程體,它包含了要執行的這個線程的內容,run()運行結束,此線程終止,然後CPU再調度其它線程。

(2)sleep()、wait()、yield()的區別

sleep()方法屬於Thread類,wait()方法屬於Object類。
調用sleep()方法,線程不會釋放對象鎖,只是暫停執行指定的時間,會自動恢復運行狀態;調用wait()方法,線程會放棄對象鎖,進入等待此對象的等待鎖定池,不調用notify()方法,線程永遠處於就緒(掛起)狀態。

yield()直接由運行狀態跳回就緒狀態,表示退讓線程,讓出CPU,讓CPU調度器重新調度。禮讓可能成功,也可能不成功,也就是說,回到調度器和其他線程進行公平競爭。

1.Android線程的原則

(1)為什麼不能再主線程中做耗時操作
防止ANR, 不能在UI主線程中做耗時的操作,因此我們可以把耗時的操作放在另一個工作線程中去做。操作完成後,再通知UI主線程做出相應的響應。這就需要掌握線程間通信的方式了。 在Android中提供了兩種線程間的通信方式:一種是AsyncTask機制,另一種是Handler機制。

(2)為什麼不能在非UI線程中更新UI 因為Android的UI線程是非線程安全的,應用更新UI,是調用invalidate()方法來實現界面的重繪,而invalidate()方法是非線程安全的,也就是說當我們在非UI線程來更新UI時,可能會有其他的線程或UI線程也在更新UI,這就會導致界面更新的不同步。因此我們不能在非UI主線程中做更新UI的操作。

2.Android實現多線程的幾種方式

3.為何需要多線程

多線程的本質就是非同步處理,直觀一點說就是不要讓用戶感覺到「很卡」。

4.多線程機制的核心是啥

多線程核心機制是Handler

推薦Handler講解視頻: 面試總被問到Handler?帶你從源碼的角度解讀Handler核心機制

根據上方提到的 多進程、多線程、Handler 問題,我整理了一套 Binder與Handler 機制解析的學習文檔,提供給大家進行學習參考,有需要的可以 點擊這里直接獲取!!! 裡面記錄許多Android 相關學習知識點。

⑵ Android性能優化(三)啟動速度優化

Android性能優化(三)啟動速度優化

一、App啟動流程

App的啟動流程主要包括以下幾個步驟:

  1. 點擊桌面App圖標:Launcher進程採用Binder IPC向AMS(Activity Manager Service)進程發起startActivity請求。
  2. AMS接收請求:AMS接收到請求後,向zygote進程發送創建進程的請求。
  3. Zygote進程fork新進程:Zygote進程fork出新的子進程,即App進程。
  4. App進程attachApplication:App進程通過Binder IPC向AMS進程發起attachApplication請求。
  5. AMS准備並發送調度請求:AMS進程在收到請求後,進行一系列准備工作,再通過binder IPC向App進程發送scheleLaunchActivity請求。
  6. App進程處理LAUNCH_ACTIVITY消息:App進程的binder線程(ApplicationThread)在收到請求後,通過handler向主線程發送LAUNCH_ACTIVITY消息。
  7. 主線程創建Activity:主線程在收到Message後,通過反射機制創建目標Activity,並回調Activity.onCreate()等方法。
  8. App啟動完成:執行完onCreate/onStart/onResume方法,UI渲染結束後,用戶便可以看到App的主界面。

七、啟動優化的具體點

  1. 合理使用非同步初始化、延遲初始化和懶載入機制:對於不需要在啟動時就初始化的資源或功能,可以採用非同步初始化、延遲初始化或懶載入機制,以減少啟動時的耗時。

  2. 避免啟動過程中的耗時操作:如資料庫I/O操作等,應盡量避免在主線程執行,可以放在子線程或非同步任務中處理。

  3. 類載入優化:通過提前非同步執行類載入,可以減少啟動時的類載入時間。

  4. 合理使用IdleHandler進行延遲初始化:IdleHandler可以在主線程空閑時執行一些延遲初始化的任務,從而避免在啟動時佔用主線程時間。

  5. 簡化布局:優化布局文件,減少不必要的嵌套和復雜的布局結構,可以提高UI渲染的速度,從而減少啟動時間。

通過以上方法,可以有效地優化App的啟動速度,提升用戶體驗。在下一篇文章中,我們將繼續探討Android性能優化的其他方面——卡頓優化。

⑶ android開發中線程有幾種狀態,分別是哪些

【答案】:1)、新建狀態(New):新創建了一個線程對象。
2)、就緒狀態(Runnable):線程對象創建後,其他線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。
3)、運行狀態(Running):就緒狀態的線程獲取了CPU,執行run()方法。
4)、阻塞狀態(Blocked):阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種:
(一)、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。
(二)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池中。
(三)、其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。
5)、死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。
當調用start方法的時候,該線程就進入就緒狀態。等待CPU進行調度執行,此時還沒有真正執行線程。
當調用run方法的時候,是已經被CPU進行調度,執行線程的主要任務。

⑷ android系統中出現的nativecrash反映的是系統哪一層的問題呀是framework層的問題嗎

Android平台程序崩潰的類型及原因列舉

  1. ANR(可見ANR):

    發生場景:應用發生ANR。

    崩潰症狀:系統彈出窗口詢問用戶選擇「Force Close」或者「Wait」。

    "Force Close"將殺掉發生ANR的應用進程。"Wait"將會等待系統擇機恢復此應用進程。

    發生原因:(1)應用主線程卡住,對其他請求響應超時。(2)死鎖。(3)系統反應遲鈍。(4)CPU負載過重。

  2. Force Close:

    發生場景:應用進程崩潰。

    崩潰症狀:系統彈出窗口提示用戶某進程崩潰。

    發生原因:空指向異常或者未捕捉的異常。

  3. Tombstones:

    發生場景:Native層崩潰

    崩潰症狀:如果發生崩潰的native層和UI有關聯(比如Browser),我們可以在UI上發現這個崩潰。

    如果發生崩潰的native層是在後台並且和UI沒有直接聯系,那麼對於用戶來說是不可見的,如果是debug版本可能會有Log列印出當時的底層現場。

    發生原因:各種各樣,需要具體情況具體分析。

  4. 系統服務崩潰(System Server Crash):

    發生場景:系統服務是Android核心進程,此服務進程發生崩潰。

    崩潰症狀:手機重啟到Android啟動界面

    發生原因:(1)系統服務看門狗發現異常。(2)系統服務發生未捕獲異常。(3)OOM。(4)系統服務Native發生Tombstone。

  5. Kernel Panics:

    發生場景:Linux內核發生嚴重錯誤

    崩潰症狀:手機從bootloader開始完全重啟

    發生原因:(1)Linux內核內存空間發生內存崩潰。(2)內核看門狗發現異常。(3)空指針操作內核。

⑸ android開發等待一段時間後執行下一條語句,但是thread.sleep(30000)之後線程就掛起了

android的開發思路中,基本上都是由子線程去執行任務的,然後執行完了之後發回message再由handler去處理。這樣才不會影響程序連貫性的操作。
你這個需要sleep之後再執行的語句,就放到子線程中去。

⑹ android線程中wait,join,sleep,yield, notify,notifyall,synchronized區別及聯系是什麼

【答案】:1).sleep()方法
在指定時間內讓當前正在執行的線程暫停執行,但不會釋放「鎖標志」。不推薦使用。sleep()使當前線程進入阻塞狀態,在指定時間內不會執行。
2).wait()方法
在其他線程調用對象的notify或notifyAll方法前,導致當前線程等待。線程會釋放掉它所佔有的「鎖標志」,從而使別的線程有機會搶占該鎖。
喚醒當前對象鎖的等待線程使用notify或notifyAll方法,waite() 和notify()必須在synchronized函數或synchronized block中進行調用。
3).yield方法
暫停當前正在執行的線程對象。yield()只是使當前線程重新回到可執行狀態,所以執行3)yield()的線程有可能在進入到可執行狀態後馬上又被執行。yield()只能使同優先順序或更高優先順序的線程有執行的機會。
4).join方法
等待該線程終止。等待調用join方法的線程結束,再繼續執行。如:t.join();//主要用於等待t線程運行結束,若無此句,main則會執行完畢,導致結果不可預測。

⑺ Android 系統運行機制 【Looper】【Choreographer】篇

目錄:
1 MessageQueue next()
2 Vsync
3 Choreographer doFrame
4 input

系統是一個無限循環的模型, Android也不例外,進程被創建後就陷入了無限循環的狀態

系統運行最重要的兩個概念:輸入,輸出。

Android 中輸入 輸出 的往復循環都是在 looper 中消息機制驅動下完成的

looper 的循環中, messageQueue next 取消息進行處理, 處理輸入事件, 進行輸出, 完成和用戶交互

應用生命周期內會不斷 產生 message 到 messageQueue 中, 有: java層 也有 native層

其中最核心的方法就是 messageQueue 的 next 方法, 其中會先處理 java 層消息, 當 java 層沒有消息時候, 會執行 nativePollOnce 來處理 native 的消息 以及監聽 fd 各種事件

從硬體來看, 屏幕不會一直刷新, 屏幕的刷新只需要符合人眼的視覺停留機制

24Hz , 連續刷新每一幀, 人眼就會認為畫面是流暢的

所以我們只需要配合上這個頻率, 在需要更新 UI 的時候執行繪制操作

如何以這個頻率進行繪制每一幀: Android 的方案是 Vsync 信號驅動。

Vsync 信號的頻率就是 24Hz , 也就是每隔 16.6667 ms 發送一次 Vsync 信號提示系統合成一幀。

監聽屏幕刷新來發送 Vsync 信號的能力,應用層 是做不到的, 系統是通過 jni 回調到 Choreographer 中的 Vsync 監聽, 將這個重要信號從 native 傳遞到 java 層。

總體來說 輸入事件獲取 Vsync信號獲取 都是先由 native 捕獲事件 然後 jni 到 java 層實現業務邏輯

執行的是 messageQueue 中的關鍵方法: next

next 主要的邏輯分為: java 部分 和 native 部分

java 上主要是取java層的 messageQueue msg 執行, 無 msg 就 idleHandler

java層 無 msg 會執行 native 的 pollOnce@Looper

native looper 中 fd 監聽封裝為 requestQueue, epoll_wait 將 fd 中的事件和對應 request 封裝為 response 處理, 處理的時候會調用 fd 對應的 callback 的 handleEvent

native 層 pollOnce 主要做的事情是:

vsync 信號,輸入事件, 都是通過這樣的機制完成的。

epoll_wait 機制 拿到的 event , 都在 response pollOnce pollInner 處理了

這里的 dispatchVsync 從 native 回到 java 層

native:

java:

收到 Vsync 信號後, Choreographer 執行 doFrame

應用層重要的工作幾乎都在 doFrame 中

首先看下 doFrame 執行了什麼:

UI 線程的核心工作就在這幾個方法中:

上述執行 callback 的過程就對應了圖片中 依次處理 input animation traversal 這幾個關鍵過程

執行的周期是 16.6ms, 實際可能因為一些 delay 造成一些延遲、丟幀

input 事件的整體邏輯和 vsync 類似

native handleEvent ,在 NativeInputEventReceiver 中處理事件, 區分不同事件會通過 JNI

走到 java 層,WindowInputEventReceiver 然後進行分發消費

native :

java:

input事件的處理流程:

輸入event deliverInputEvent

deliver的 input 事件會來到 InputStage

InputStage 是一個責任鏈, 會分發消費這些 InputEvent

下面以滑動一下 recyclerView 為例子, 整體邏輯如下:

vsync 信號到來, 執行 doFrame,執行到 input 階段

touchEvent 消費, recyclerView layout 一些 ViewHolder

scroll 中 fill 結束,會執行 一個 recyclerView viewProperty 變化, 觸發了invalidate

invalidate 會走硬體加速, 一直到達 ViewRootImpl , 從而將 Traversal 的 callback post choreographer執行到 traversal 階段就會執行

ViewRootImpl 執行 performTraversal , 會根據目前是否需要重新layout , 然後執行layout, draw 等流程

整個 input 到 traversal 結束,硬體繪制後, sync 任務到 GPU , 然後合成一幀。

交給 SurfaceFlinger 來顯示。

SurfaceFlinger 是系統進程, 每一個應用進程是一個 client 端, 通過 IPC 機制,client 將圖像顯示工作交給 SurfaceFlinger

launch 一個 app:

熱點內容
編程有用么 發布:2025-09-17 20:22:01 瀏覽:159
ftp怎麼發文件到伺服器 發布:2025-09-17 20:12:14 瀏覽:143
怎麼設置筆記本的密碼怎麼設置密碼 發布:2025-09-17 20:12:12 瀏覽:316
foxmail上傳附件失敗 發布:2025-09-17 20:03:54 瀏覽:359
128伺服器是什麼意思 發布:2025-09-17 19:49:54 瀏覽:609
yum安裝phpfpm 發布:2025-09-17 19:48:49 瀏覽:572
斗羅大陸我的世界伺服器游戲 發布:2025-09-17 19:46:14 瀏覽:21
國產壓縮餅干 發布:2025-09-17 19:25:55 瀏覽:156
演算法p8 發布:2025-09-17 19:22:37 瀏覽:708
車的哪些配置是必須有的 發布:2025-09-17 19:00:32 瀏覽:1006