Android部分

分類:編程 時間:2017-02-21

  1. Activity 系列問題
    1.1 繪制Activity生命周期流程圖
    生命周期

1.2 介紹下不同場景下Activity生命周期的變化過程

啟動Activity: onCreate()—>onStart()—>onResume(),Activity進入運行狀態。
Activity退居後臺: 當前Activity轉到新的Activity界面或按Home鍵回到主屏: onPause()—>onStop(),進入停滯狀態。
Activity返回前臺: onRestart()—>onStart()—>onResume(),再次回到運行狀態。
Activity退居後臺,且系統內存不足, 系統會殺死這個後臺狀態的Activity,若再次回到這個Activity,則會走onCreate()–>onStart()—>onResume()
鎖定屏與解鎖屏幕 只會調用onPause(),而不會調用onStop方法,開屏後則調用onResume()
1.3 內存不足時系統會殺掉後臺的Activity,若需要進行一些臨時狀態的保存,在哪個方法進行?
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命周期方法,它們不同於 onCreate()、onPause()等生命周期方法,它們並不一定會被觸發。當應用遇到意外情況(如:內存不足、用戶直接按Home鍵)由系統銷毀一個Activity,onSaveInstanceState() 會被調用。但是當用戶主動去銷毀一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。除非該activity是被用戶主動銷毀的,通常onSaveInstanceState()只適合用於保存一些臨時性的狀態,而onPause()適合用於數據的持久化保存。
1.4 onSaveInstanceState()被執行的場景有哪些:

系統不知道你按下HOME後要運行多少其他的程序,自然也不知道activity A是否會被銷毀,因此系統都會調用onSaveInstanceState(),讓用戶有機會保存某些非永久性的數據。以下幾種情況的分析都遵循該原則

當用戶按下HOME鍵時
長按HOME鍵,選擇運行其他的程序時
鎖屏時
從activity A中啟動一個新的activity時
屏幕方向切換時 

1.5 介紹Activity的幾中啟動模式,並簡單說說自己的理解或者使用場景
standard:這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。
singleTop: 如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。
singleTask:如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
singleInstance:在一個新棧中創建該Activity的實例,並讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。
2. Service系列問題
2.1 註冊Service需要註意什麽

Service還是運行在主線程當中的,所以如果需要執行一些復雜的邏輯操作,最好在服務的內部手動創建子線程進行處理,否則會出現UI線程被阻塞的問題

2.2 Service與Activity怎麽實現通信

方法一:
添加一個繼承Binder的內部類,並添加相應的邏輯方法
重寫Service的onBind方法,返回我們剛剛定義的那個內部類實例
Activity中創建一個ServiceConnection的匿名內部類,並且重寫裏面的onServiceConnected方法和onServiceDisconnected方法,這兩個方法分別會在活動與服務成功綁定以及解除綁定的時候調用,在onServiceConnected方法中,我們可以得到一個剛才那個service的binder對象,通過對這個binder對象進行向下轉型,得到我們那個自定義的Binder實例,有了這個實例,做可以調用這個實例裏面的具體方法進行需要的操作了

方法二 通過BroadCast(廣播)的形式 當我們的進度發生變化的時候我們發送一條廣播,然後在Activity的註冊廣播接收器,接收到廣播之後更新視圖

2.3介紹源碼中binder機制
我後面的博客會有後續
2.4 IntentService與Service的區別
IntentService是Service的子類,是一個異步的,會自動停止的服務,很好解決了傳統的Service中處理完耗時操作忘記停止並銷毀Service的問題

會創建獨立的worker線程來處理所有的Intent請求;
會創建獨立的worker線程來處理onHandleIntent()方法實現的代碼,無需處理多線程問題;
所有請求處理完成後,IntentService會自動停止,無需調用stopSelf()方法停止Service;
為Service的onBind()提供默認實現,返回null;
為Service的onStartcommand提供默認實現,將請求Intent添加到隊列中;
IntentService不會阻塞UI線程,而普通Serveice會導致ANR異常
Intentservice若未執行完成上一次的任務,將不會新開一個線程,是等待之前的任務完成後,再執行新的任務,等任務完成後再次調用stopSelf()

  1. Handle系列問題
    作者:閉關寫代碼
    鏈接:https://www.nowcoder.com/discuss/3244
    來源:牛客網

3.1 介紹Handle的機制

Handler通過調用sendmessage方法把消息放在消息隊列MessageQueue中,Looper負責把消息從消息隊列中取出來,重新再交給Handler進行處理,三者形成一個循環
通過構建一個消息隊列,把所有的Message進行統一的管理,當Message不用了,並不作為垃圾回收,而是放入消息隊列中,供下次handler創建消息時候使用,提高了消息對象的復用,減少系統垃圾回收的次數
每一個線程,都會單獨對應的一個looper,這個looper通過ThreadLocal來創建,保證每個線程只創建一個looper,looper初始化後就會調用looper.loop創建一個MessageQueue,這個方法在UI線程初始化的時候就會完成,我們不需要手動創建 

3.2 談談對HandlerThread的理解
HandlerThread本質上就是一個普通Thread,只不過內部建立了Looper.
特點:
HandlerThread將loop轉到子線程中處理,說白了就是將分擔MainLooper的工作量,降低了主線程的壓力,使主界面更流暢。
開啟一個線程起到多個線程的作用。處理任務是串行執行,按消息發送順序進行處理。
相比多次使用new Thread(){…}.start()這樣的方式節省系統資源。
但是由於每一個任務都將以隊列的方式逐個被執行到,一旦隊列中有某個任務執行時間過長,那麽就會導致後續的任務都會被延遲處理。
HandlerThread擁有自己的消息隊列,它不會幹擾或阻塞UI線程。
通過設置優先級就可以同步工作順序的執行,而又不影響UI的初始化;
總結:HandlerThread比較適用於單線程+異步隊列的場景,比如IO讀寫操作,耗時不多而且也不會產生較大的阻塞。對於網絡IO操作,HandlerThread並不適合,因為它只有一個線程,還得排隊一個一個等著。
4. ListView系列問題
4.1 ListView卡頓的原因與性能優化,越多越好
1.重用converView: 通過復用converview來減少不必要的view的創建,另外Infalte操作會把xml文件實例化成相應的View實例,屬於IO操作,是耗時操作。

2.減少findViewById()操作: 將xml文件中的元素封裝成viewholder靜態類,通過converview的setTag和getTag方法將view與相應的holder對象綁定在一起,避免不必要的findviewbyid操作

3.避免在 getView 方法中做耗時的操作: 例如加載本地 Image 需要載入內存以及解析 Bitmap ,都是比較耗時的操作,如果用戶快速滑動listview,會因為getview邏輯過於復雜耗時而造成滑動卡頓現象。用戶滑動時候不要加載圖片,待滑動完成再加載,可以使用這個第三方庫glide

4.Item的布局層次結構盡量簡單,避免布局太深或者不必要的重繪

5.盡量能保證 Adapter 的 hasStableIds() 返回 true 這樣在 notifyDataSetChanged() 的時候,如果item內容並沒有變化,ListView 將不會重新繪制這個 View,達到優化的目的

6.在一些場景中,ScollView內會包含多個ListView,可以把listview的高度寫死固定下來
ScollView在快速滑動過程中需要大量計算每一個listview的高度,阻塞了UI線程導致卡頓現象出現,如果我們每一個item的高度都是均勻的,可以通過計算把listview的高度確定下來,避免卡頓現象出現

7.使用 RecycleView 代替listview
每個item內容的變動,listview都需要去調用notifyDataSetChanged來更新全部的item,太浪費性能了。RecycleView可以實現當個item的局部刷新,並且引入了增加和刪除的動態效果,在性能上和定制上都有很大的改善
8.ListView 中元素避免半透明
半透明繪制需要大量乘法計算,在滑動時不停重繪會造成大量的計算,在比較差的機子上會比較卡。 在設計上能不半透明就不不半透明。實在要弄就把在滑動的時候把半透明設置成不透明,滑動完再重新設置成半透明。
9.盡量開啟硬件加速
硬件加速提升巨大,避免使用一些不支持的函數導致含淚關閉某個地方的硬件加速。當然這一條不只是對 ListView
4.2 怎麽實現一個部分更新的 ListView?
4.3 怎麽實現ListView多種布局?
4.4 ListView與數據庫綁定的實現


Tags:

文章來源:


ads
ads

相關文章
ads

相關文章

ad