Android復(fù)習(xí)筆記

啟動Activity的幾種方法有什么區(qū)別?

  • standard
    創(chuàng)建新對象
  • singleInstance
    只有一個實(shí)例
  • singleTask
    新建一個棧
  • singleTop
    如果在頂端就不創(chuàng)建直接用,否則創(chuàng)建。

講解你的項(xiàng)目架構(gòu)

常用的設(shè)計(jì)模式

代理和動態(tài)代理

1.靜態(tài)代理

2.動態(tài)代理

實(shí)現(xiàn) InvocationHandler

bind/invoke

AOP編程: Spring MVC,Structs的攔截器

觀察者模式

Adapter模式

仲裁模式

單例(線程安全)

  • 線程安全單例
    • 1.饑餓式
    • 2.懶漢式
    • 3.靜態(tài)成員類
    • 4.枚舉
  • 內(nèi)存泄漏問題
    單例傳入Context會引起內(nèi)存泄漏,無法釋放,改成傳入ApplicationContext
    或者參數(shù)不要持有,僅僅在單例的方法中參入,而不是構(gòu)造函數(shù)中傳入。

簡單工廠有什么特點(diǎn)?

Android多設(shè)備UI適配

  • dp/sp
  • 百分比

Android熱更新原理

Android內(nèi)存泄漏

內(nèi)存泄漏

如果一個不需要再使用的對象(強(qiáng)引用)仍然被其他對象持有引用,造成該對象無法被系統(tǒng)回收。

1.什么情況下會造成內(nèi)存泄漏?

  • 單例導(dǎo)致內(nèi)存泄漏

  • 靜態(tài)變量導(dǎo)致內(nèi)存泄漏

  • 非靜態(tài)內(nèi)部類導(dǎo)致內(nèi)存泄漏

    • Handler/Thread/AsyncTask

    靜態(tài)內(nèi)部類+弱引用
    mHandler.removeCallbacksAndMessages(null);

  • 緩存沒有釋放不再引用的對象

  • 未取消注冊或回調(diào)導(dǎo)致內(nèi)存泄露

  • Timer和TimerTask導(dǎo)致內(nèi)存泄露

    cancel timer

  • 集合中的對象未清理造成內(nèi)存泄露

  • 資源未關(guān)閉或釋放導(dǎo)致內(nèi)存泄露

  • 屬性動畫造成內(nèi)存泄露

  • WebView造成內(nèi)存泄露

2.如何調(diào)試分析?

  • WeTest 騰訊
  • in
  • Android MAT
  • LeakCanary Square

Android Lint

  • 靜態(tài)代碼檢查
  • 靜態(tài)代碼檢查框架
  • Lint的優(yōu)點(diǎn)
  1. 功能強(qiáng)大,Lint支持Java源文件、class文件、資源文件、Gradle等文件的檢查。
  2. 擴(kuò)展性強(qiáng),支持開發(fā)自定義Lint規(guī)則。
  3. 配套工具完善,Android Studio、Android Gradle插件原生支持Lint工具。
  4. Lint專為Android設(shè)計(jì),原生提供了幾百個實(shí)用的Android相關(guān)檢查規(guī)則。
  5. 有Google官方的支持,會和Android開發(fā)工具一起升級完善。

Activity傳遞大數(shù)據(jù)怎么辦?

  • Bundle最大約1M
    TransactionTooLargeException
    The Binder transaction failed because it was too large
  • 傳遞大數(shù)據(jù)(比如bitmap)盡量避免采用bundle傳遞
    • 寫文件或數(shù)據(jù)庫
    • 寫全局緩存(需要和調(diào)用者在一個進(jìn)程)
    • 單例(需要和調(diào)用者在一個進(jìn)程)

Service和IntentService的區(qū)別

1.Service

Service 是長期運(yùn)行在后臺的應(yīng)用程序組件。

Service 不是一個單獨(dú)的進(jìn)程,它和應(yīng)用程序在同一個進(jìn)程中,Service 也不是一個線程,它和線程沒有任何關(guān)系,所以它不能直接處理耗時操作。如果直接把耗時操作放在 Service 的 onStartCommand() 中,很容易引起 ANR .如果有耗時操作就必須開啟一個單獨(dú)的線程來處理。

2.IntentService

IntentService 是繼承于 Service 并處理異步請求的一個類,在 IntentService 內(nèi)有一個工作線程來處理耗時操作,啟動 IntentService 的方式和啟動傳統(tǒng) Service 一樣,同時,當(dāng)任務(wù)執(zhí)行完后,IntentService 會自動停止,而不需要我們?nèi)ナ謩涌刂?。另外,可以啟?IntentService 多次,而每一個耗時操作會以工作隊(duì)列的方式在IntentService 的 onHandleIntent 回調(diào)方法中執(zhí)行,并且,每次只會執(zhí)行一個工作線程,執(zhí)行完第一個再執(zhí)行第二個,以此類推。

而且,所有請求都在一個單線程中,不會阻塞應(yīng)用程序的主線程(UI Thread),同一時間只處理一個請求。

IntentService是一個通過Context.startService(Intent)啟動可以處理異步請求的Service,使用時你只需要繼承IntentService和重寫其中的onHandleIntent(Intent)方法接收一個Intent對象,在適當(dāng)?shù)臅r候會停止自己(一般在工作完成的時候). 所有的請求的處理都在一個工作線程中完成,它們會交替執(zhí)行(但不會阻塞主線程的執(zhí)行),一次只能執(zhí)行一個請求。

這是一個基于消息的服務(wù),每次啟動該服務(wù)并不是馬上處理你的工作,而是首先會創(chuàng)建對應(yīng)的Looper,Handler并且在MessageQueue中添加的附帶客戶Intent的Message對象,當(dāng)Looper發(fā)現(xiàn)有Message的時候接著得到Intent對象通過在onHandleIntent((Intent)msg.obj)中調(diào)用你的處理程序.處理完后即會停止自己的服務(wù).意思是Intent的生命周期跟你的處理的任務(wù)是一致的.所以這個類用下載任務(wù)中非常好,下載任務(wù)結(jié)束后服務(wù)自身就會結(jié)束退出.

應(yīng)用內(nèi)廣播

LocalBroadcastManager
避免廣播敏感信息,被其他惡意的receiver接收到.

Handler一定要在主線程實(shí)例化嗎?new Handler()和new Handler(Looper.getMainLooper())的區(qū)別

場景 當(dāng)前在主線程 當(dāng)前在工作線程
需要刷新UI Handler handler = new Handler(); Handler handler = new Handler(Looper.getMainLooper());
不用刷新ui,只是處理消息 Handler handler = new Handler(); Looper.prepare(); Handler handler = new Handler();Looper.loop();或Handler handler = new Handler(Looper.getMainLooper());

1. Handler handler = new Handler();默認(rèn)使用當(dāng)前線程的looper

2. 如果需要刷新UI,那么1的代碼需要在主線程創(chuàng)建。如果不是在主線程可以通過傳入?yún)?shù)指定主線程的looper。

Handler handler = new Handler(Looper.getMainLooper());

3.不用刷新ui,只是處理消息。 當(dāng)前線程如果是主線程的話,Handler handler = new Handler();不是主線程的話,Looper.prepare(); Handler handler = new Handler();Looper.loop();或者Handler handler = new Handler(Looper.getMainLooper());

HandlerThread的特點(diǎn)

  • HandlerThread將loop轉(zhuǎn)到子線程中處理,說白了就是將分擔(dān)MainLooper的工作量,降低了主線程的壓力,使主界面更流暢。

  • 開啟一個線程起到多個線程的作用。處理任務(wù)是串行執(zhí)行,按消息發(fā)送順序進(jìn)行處理。HandlerThread本質(zhì)是一個線程,在線程內(nèi)部,代碼是串行處理的。

  • 但是由于每一個任務(wù)都將以隊(duì)列的方式逐個被執(zhí)行到,一旦隊(duì)列中有某個任務(wù)執(zhí)行時間過長,那么就會導(dǎo)致后續(xù)的任務(wù)都會被延遲處理。

  • HandlerThread擁有自己的消息隊(duì)列,它不會干擾或阻塞UI線程。

  • 對于網(wǎng)絡(luò)IO操作,HandlerThread并不適合,因?yàn)樗挥幸粋€線程,還得排隊(duì)一個一個等著。

Android架構(gòu)設(shè)計(jì)

  • Android Architecture Components
  • 反編譯其他APP來學(xué)習(xí)
  • 根據(jù)APP業(yè)務(wù)特點(diǎn)來確定架構(gòu)
  • 分層設(shè)計(jì)
  1. UI (Activity/Fragment/Views

UI相關(guān)

1.不能使用 ScrollView 包裹 ListView/GridView/ExpandableListVIew

因?yàn)檫@ 樣會把 ListView 的所有 Item 都加載到內(nèi)存中,要消耗巨大的內(nèi)存和 cpu 去繪制圖面。

推薦使用 NestedScrollView

Android更新UI的幾種方法

1.Handler+View.invalidate+Thread+Runnable

2.View.postInvalidate+Thread+Runnable

postInvalidate就是把message(MSG_INVALIDATE,view)丟給主線程mHandler,mHandler收到后view.invalidate

3.Handler+Worker Thread

自定義主線程Handler,從Worker Thread發(fā)送消息

4.Worker Thread 中runOnUiThread

public final void runOnUiThread(Runnable action) {  
       if (Thread.currentThread() != mUiThread) {  
           mHandler.post(action);//將Runnable Post到消息隊(duì)列,由內(nèi)部的mHandler來處理,實(shí)際上也是Handler的處理方式  
       } else {  
           action.run();//已經(jīng)在UI線程,直接運(yùn)行。  
       }  
   }  

5.AysncTask更新UI

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,167評論 25 708
  • java 接口的意義-百度 規(guī)范、擴(kuò)展、回調(diào) 抽象類的意義-樂視 為其子類提供一個公共的類型封裝子類中得重復(fù)內(nèi)容定...
    交流電1582閱讀 2,389評論 0 11
  • 一個人要經(jīng)歷多少,才能找到真愛。世間美好的東西很多,總有一種最適合你。 就像一位書法屆的友人告訴我,無論你見識了多...
    官小姐不當(dāng)官閱讀 503評論 4 5
  • 根據(jù)世界衛(wèi)生組織國際癌癥研究機(jī)構(gòu)2017年10月27日公布的致癌物清單,整理了一下。 看看哪些是我們?nèi)粘D芙佑|到的...
    大喜就是我閱讀 654評論 0 0
  • 最近一直單曲循環(huán)陳奕迅的 愛情呼叫轉(zhuǎn)移,粵語版 富士山下,人這一輩子最怕聽懂一首歌,那種揉碎了歌詞,然后在你的生活...
    石頭_aa94閱讀 434評論 0 2

友情鏈接更多精彩內(nèi)容