① android 中 自己寫的activity 的優先順序怎麼才能大於系統的 譬如來電 自己已經獲取號碼並寫了一個activity
Android中,Activity的級別永完都沒有來電這么高級別,因為手機最主要的功能,還是用來通話。
關於Android中的進程級別:
1、foreground process
正處於activity resume狀態
正處於bound服務交互的狀態
正處於服務在前台運行的狀態(StartForeGround()被調用)
Service生命周期正在被執行(onCreate(),onStart(),onDestroy())
BroadcastReceiver正在執行onReceive()方法
殺死foreground需要用戶響應,因為這個安全優先順序是最高的
是用戶操作所必須的,任一時間下,僅有少數進程會處於前台,僅當內存實在無法供給它們維持同時運行時才會被殺死。一般來說,在這種情況下,設備依然處於使用虛擬內存的狀態,必須要殺死一些前台進程以用戶界面保持響應。
•Android會依據進程中當前活躍組件的重要程度來盡可能高的估量一個進程的級別。比如說,如果一個進程中同時有一個服務和一個可視的activity,則進程會被判定為可視進程,而不是服務進程。
2、visible process
activity不在前端顯示,但也沒有完全隱藏,能夠看得見,比如彈出一個對話框
一個bound到visible或者foreground的activity的service
沒有前台組件,但仍可被用戶在屏幕上所見。當滿足如下任一條件時,進程被認為是可視的:
• 它包含著一個不在前台,但仍然為用戶可見的activity(它的onPause()方法被調用)。這種情況可能出現在以下情況:比如說,前台activity是一個對話框,而之前的 activity位於其下並可以看到。
• 它包含了一個綁定至一個可視的activity的服務。
可視進程依然被視為是很重要的,非到不殺死它們便無法維持前台進程運行時,才會被殺死。
3、Service process
正在運行的,不在上述兩種狀態的service
是由 startService() 方法啟動的服務,它不會變成上述兩類。盡管服務進程不會直接為用戶所見,但它們一般都在做著用戶所關心的事情(比如在後台播放mp3或者從網上下載東 西)。所以系統會盡量維持它們的運行,除非系統內存不足以維持前台進程和可視進程的運行需要。
4、background process
不可見狀態的activity進程,onstop被調用
包含目前不為用戶所見的activity(Activity對象的 onStop() 方法已被調用)。這些進程與用戶體驗沒有直接的聯系,可以在任意時間被殺死以回收內存供前台進程、可視進程以及服務進程使用。一般來說,會有很多背景進程 運行,所以它們一般存放於一個LRU(最後使用)列表中以確保最後被用戶使用的activity最後被殺死。如果一個activity正確的實現了生命周 期方法,並捕獲了正確的狀態,則殺死它的進程對用戶體驗不會有任何不良影響。
5、empty process
沒有運行任何component的進程,保留這個進程主要是為了緩存的需要
不包含任何活動應用程序組件。這種進程存在的唯一原因是做為緩存以改善組件再次於其中運行時的啟動時間。系統經常會殺死這種進程以保持進程緩存和系統內核緩存之間的平衡。
此外,一個進程的級別可能會由於其它進程依賴於它而升高。一個為其它進程提供 服務的進程級別永遠高於使用它服務的進程。比如說,如果A進程中的內容提供者為進程B中的客戶端提供服務,或進程A中的服務為進程B中的組件所綁定,則A 進程最低也會被視為與進程B擁有同樣的重要性。
② 每個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怎麼提高線程的優先順序
線程調度 計算機通常只有一個CPU,在任意時刻只能執行一條機器指令,每個線程只有獲得CPU的使用權才能執行指令.所謂多線程的並發運行,其實是指從宏觀上看,各個線程輪流獲得CPU的使用權,分別執行各自的任務.在運行池中,會有多個處於就緒狀態的線程在等待CPU,java虛擬機的一項任務就是負責線程的調度,線程調度是指按照特定機制為多個線程分配CPU的使用權. 有兩種調度模型:分時調度模型和搶占式調度模型。 分時調度模型是指讓所有的線程輪流獲得cpu的使用權,並且平均分配每個線程佔用的CPU的時間片這個也比較好理解。 java虛擬機採用搶占式調度模型,是指優先讓可運行池中優先順序高的線程佔用CPU,如果可運行池中的線程優先順序相同,那麼就隨機選擇一個線程,使其佔用CPU。處於運行狀態的線程會一直運行,直至它不得不放棄CPU。 一個線程會因為以下原因而放棄CPU。 1 java虛擬機讓當前線程暫時放棄CPU,轉到就緒狀態,使其它線程或者運行機會。 2 當前線程因為某些原因而進入阻塞狀態 3 線程結束運行 需要注意的是,線程的調度不是跨平台的,它 不僅僅取決於java虛擬機,還依賴於操作系統。在某些操作系統中,只要運行中的線程沒有遇到阻塞,就不會放棄CPU;在某些操作系統中,即使線程沒有遇到阻塞,也會運行一段時間後放棄CPU,給其它線程運行的機會。 java的線程調度是不分時的,同時啟動多個線程後,不能保證各個線程輪流獲得均等的CPU時間片。 如果希望明確地讓一個線程給另外一個線程運行的機會,可以採取以下辦法之一。 調整各個線程的優先順序 讓處於運行狀態的線程調用Thread.sleep()方法 讓處於運行狀態的線程調用Thread.yield()方法 讓處於運行狀態的線程調用另一個線程的join()方法
④ 針對Android的性能優化集中哪些方面
一、概要:
本文主要以Android的渲染機制、UI優化、多線程的處理、緩存處理、電量優化以及代碼規范等幾方面來簡述Android的性能優化
二、渲染機制的優化:
大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。
Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染, 如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。
*關於JobScheler的更多知識可以參考http://hukai.me/android-training-course-in-chinese/background-jobs/scheling/index.html
七、代碼規范
1)for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。
2)明白垃圾回收機制,避免頻繁GC,內存泄漏,OOM(有機會專門說)
3)合理使用數據類型,StringBuilder代替String,少用枚舉enum,少用父類聲明(List,Map)
4)如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程創建開銷。
5)你要知道單例的好處,並正確的使用它。
6)多用常量,少用顯式的"action_key",並維護一個常量類,別重復聲明這些常量。
7)如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,工廠模式,觀察者模式,這些能幫助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一發而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。
8)View中設置緩存屬性.setDrawingCache為true.
9)cursor的使用。不過要注意管理好cursor,不要每次打開關閉cursor.因為打開關閉Cursor非常耗時。Cursor.require用於刷cursor.
10)採用SurfaceView在子線程刷新UI,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)
11)採用JNI,將耗時間的處理放到c/c++層來處理
12)有些能用文件操作的,盡量採用文件操作,文件操作的速度比資料庫的操作要快10倍左右
13)懶載入和緩存機制。訪問網路的耗時操作啟動一個新線程來做,而不要再UI線程來做
14)如果方法用不到成員變數,可以把方法申明為static,性能會提高到15%到20%
15)避免使用getter/setter存取field,可以把field申明為public,直接訪問
16)私有內部類要訪問外部類的field或方法時,其成員變數不要用private,因為在編譯時會生成setter/getter,影響性能。可以把外部類的field或方法聲明為包訪問許可權
17)合理利用浮點數,浮點數比整型慢兩倍
18)針對ListView的性能優化,ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。ListView中getView是性能是關鍵,這里要盡可能的優化。
getView方法中要重用view;getView方法中不能做復雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的性能
19)不用new關鍵詞創建類的實例,用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。
clone()方法不會調用任何類構造函數。在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現:
20)public static Credit getNewCredit() {
return new Credit();
}
改進後的代碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}
上面的思路對於數組處理同樣很有用。
21)乘法和除法
考慮下面的代碼:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
用移位操作替代乘法操作可以極大地提高性能。下面是修改後的代碼:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
22)ViewPager同時緩存page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。
23)每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預載入數據,以免造成浪費
24)提高下載速度:要控制好同時下載的最大任務數,同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)
25)提供載入速度:讓服務端提供不同解析度的圖片才是最好的解決方案。還有合理使用內存緩存,使用開源的框架
引用:Android性能優化的淺談
⑤ Android線程優先順序和進程oom_adj
在處理app啟動拍脊速度的時候,可以設置主線程的優先順序,保證主線程佔用的cpu足夠久。進程的oom_adj,決定了當內存不夠的時候,lmk會根據oom_adj的大小依次釋放內存。
android中對線程等級劃分如下:
設置線程的優先順序分為:android 提供的api和java sdk自帶的api
注意: 要羨鏈使用android提供的api設置,用java提供的作用不夠顯著
作用: 可以在主線程設置主線層等級;在Glide載入圖片的時候設置低優先順序。當圖片量很大的時候可以降低載入圖片線程的等級
android內存不夠了,會觸發oom機制,lowMemoryKiller會根據每個進程的oom_adj的等級,依次殺死進程,釋放內存。
lom會根據free的內存的值,來判斷kill掉哪個等級下的進程。例如當空閑內存只有64M了。會kill掉oom_adj 為12-15的進程
真實案例:應用A跳到第三方應用B,在第三方應用兄賀孫B中播放視頻,載入大量圖片,導致返回的時候,應用A走了SplashActivity。通過logcat發現A應用被kill掉了