android 基礎知識梳理

android 基礎知識梳理

這章主要介紹android基礎知識:包括4大組件、fragment、webView以及Binder的一些簡單介紹。

1activity

activity用戶交互的界面,包含4中狀態:running/paused/stopped/killer。

生命週期:-w574

activity啓動會執行onCreate()->onStart()->onResume, 點擊home鍵會執行onPause()->onStop(),注意如果內存吃緊,有可能會被回收。 再次回到原activity會執行onRestart()->onStart()->onResume()。 退出activity會執行onPause()->onStop()->onDestory()。

android進程優先級

分爲前臺/可見/服務/後臺/空

android任務棧

android中使用棧的方式來管理其中的Activity,後進先出的數據結構

activity啓動模式

1.Standard 默認模式,每次都會new一個activity實例入棧
2.SingleTop 棧頂複用,調用onNewIntent()函數。
3.SingleTask 任務棧存在啓動activity就把它移動到棧頂,當前activity之上的所有activity都被移除棧。
4.SingleInstance 系統會創建一個新的任務棧,並且這個任務棧只有他一個Activity。不過啓動會慢一些,往往用於多個應用之間切換。

scheme跳轉協議

android中scheme是一種頁面內跳轉協議,通過自定義scheme協議,可以非常方便的跳轉app中的各個頁面。

fragment

fragment爲何被稱爲第5大組件
答:首先fragment不屬於四大組件,它有自己的生命週期,同時它可以靈活的加載到activity當中去。 fragment雖然有自己的生命週期,但必須依附於activity存在。

fragment加載到activity中的2種方式

  • 方式一:添加Fragment到Activity的佈局文件當中
  • 方式二:在Activity的代碼中通過FragmentTransaction動態添加Fragment(薦).

FragmentPagerAdapter和FragmentStatePagerAdapter的區別?

一般fragment會配合viewpage使用,FragmentPagerAdapter一般用於頁面較少的情況,FragmentStatePagerAdapter用於頁面較多的情況。
-w895
-w920

Fragment生命週期

-w1326

Fragment通信

  • Fragment調用Activity方法利用getActivity()
  • 在Activity調用Fragment方法,接口回調(activity實現Fragment聲明的接口,在Fragment的onAttach中獲取接口)
  • Fragment調用Fragment方法,getActivity().findFragmentById,或者通過Fragment.setArguments(bundle);

Fragment中的add、replace、remove方法

FragmentManager中,replace是替換fragment實例,是把activity最上層的fragment替換成你想替換的fragment,add只是fragment加到activity的上層。

Service

Service(服務)是一個一種可以在後臺執行長時間運行操作而沒有用戶界面的應用組件。

生命週期方法

  • onBind()
      當另一個組件想通過調用 bindService() 與服務綁定(例如執行 RPC)時,系統將調用此方法。在此方法的實現中,必須返回 一個IBinder 接口的實現類,供客戶端onServiceConnected中可以獲取到該實例通信。無論是啓動狀態還是綁定狀態,此方法必須重寫,但在啓動狀態的情況下直接返回 null。

  • onCreate()
      首次創建服務時,系統將調用此方法來執行一次性設置程序(在調用 onStartCommand() 或onBind() 之前)。如果服務已在運行,則不會調用此方法,該方法只調用一次

  • onStartCommand()
      當另一個組件(如 Activity)通過調用 startService() 請求啓動服務時,系統將調用此方法。一旦執行此方法,服務即會啓動並可在後臺無限期運行。 如果自己實現此方法,則需要在服務工作完成後,通過調用 stopSelf() 或 stopService() 來停止服務。(在綁定狀態下,無需實現此方法。)

  • onDestroy()
      當服務不再使用且將被銷燬時,系統將調用此方法。服務應該實現此方法來清理所有資源,如線程、註冊的偵聽器、接收器等,這是服務接收的最後一個調用。

啓動模式

  • startService(Intent intent)一旦啓動,服務即可在後臺無限期運行,即使啓動服務的組件已被銷燬也不受影響,除非手動調用 stopSelf() 或 stopService() 才能停止服務, 已啓動的服務通常是執行單一操作,而且不會將結果返回給調用方。

  • bindService屬於client-server模式。service只有一個,但綁定到service上面的client可以有一個或很多個。這裏所提到的client指的是組件,比如某個Activity。
    服務的生命週期與其綁定的client息息相關。當client銷燬時,client會自動與Service解除綁定。當然,client也可以明確調用Context的unbindService()方法與Service解除綁定。當沒有任何client與Service綁定時,Service會自行銷燬。一般用於IPC通信。

BroadcastReceiver

廣播定義
廣泛應用在應用程序之間傳遞信息的機制,類似觀察者模式,通過intent可以傳遞數據。

使用場景

  • 同一個app具有多個進程不同組件之間的消息通信。有些app可能會多進程比如:定位進程,圖片進程,webview進程與主進程之間的通信。
  • 不同的app之間組件的信息通信,比如一些大廠的不同的app之間的通信。

分類

  • 普通廣播(Normal Broadcast)
  • 系統廣播(System Broadcast)
  • 有序廣播(Ordered Broadcast)
  • 粘性廣播(Sticky Broadcast)
  • App應用內廣播(Local Broadcast)優點:高效、安全,其實它內部是通過Handler實現的發送message實現的。

2中註冊方式

  • 靜態註冊:在AndroidManifest.xml裏通過標籤聲明,註冊完成就一直運行
  • 動態註冊:在代碼中調用Context.registerReceiver()方法,跟隨activity的生命週期。

內部機制

  1. 自定義BroadcastReceiver,並複寫onReceive()方法
  2. 通過Binder機制向AMS(Activity Manager Service)進行註冊。
  3. 廣播發送者通過Binder機制向AMS發送廣播
  4. AMS查找符合相應條件的BroadcastReceiver(IntentFilter/Permission)的BroadcastReceiver,將廣播發送到相應的消息隊列中。
  5. 消息循環執行拿到此廣播,回調BroadcastReceiver的onReceive()方法。

WebView

加載網頁的組件。

常見坑

  • 在Android API 16以前存在遠程代碼安全漏洞,因爲程序沒有正確限制使用
    WebView.addJavascriptInterface方法,攻擊者可以反射利用該漏洞執行任意java方法。
  • WebView最好使用代碼動態往容器裏addview(webview),銷燬時注意在onDestroy中,先從容器把webView移除,在調用removeAllViews(),或者採用另起進程加載WebView,然後在銷燬時,調用System.exit(0);
  ViewParent parent = mWebView.getParent();
        if (parent != null) {
            ((ViewGroup) parent).removeView(mWebView);
        }
        mWebView.stopLoading();
        mWebView.removeAllViews();
        mWebView.destroy();
        mWebView=null;
        super.onDestroy();    
  • WebViewClient.onPageFinished–>WebChromeClient.onProgressChanged
    onPageFinished無法確定當WebView調用這個方法的時候,網頁內容是否真的加載完畢 了。當前正在加載的網頁產生跳轉的時候這個方法可能會被多次調用,判斷網頁是否加載完成最好 用onProgressChanged中的progres==100回調。

  • 後臺耗電 WebView加載網頁,WebView會自己開啓一些線程,如果你沒有正確地將WebView銷燬的話,會導致電量居高不下。接調用System.exit(0);

  • 後臺無法釋放js 導致耗電。在Activity.onDestroy()中直接調用System.exit(0),使得應用程序完全被移出虛擬機,這樣就不會有任何問題了。
    [參考那些年在WebView上踩過的坑](https://blog.csdn.net/u012124438/article/ details/53401663)

Binder

Binder是什麼?
Binder是由四個模塊組成,Binder Driver 、Binder Client、Binder Server、 Server Manager。
Binder Client相當於客戶端,Binder Server相當於服務器, ServerManager相當於DNS服務器,Binder Driver 相當於一個路由器。
Binder Driver位於內核空間,主要負責Binder通信的建立,以及其在進程見得傳遞和Binder引用計數管理/數據包的傳輸等。Binder Server與 Binder Client之間的跨進程通信則通過Binder Driver轉發。對於 Binder Client只需要知道自己要使用Binder的名字以及該binder實體在 Server Manager中的0號引用即可。ServerManager就是一個標準的BinderServer,並且在Android中約定其在Binder通信過程中唯一標識符永遠是0。

Linux內核基礎知識

  1. 進程隔離/虛擬地址空間:進程a和進程b的地址空間不同,數據不共享,進程間互不干擾,進程間如果想要訪問需要Binder機制。
  2. 系統調用 內核有保護機制,上層和內核層抽象分離開來。
    3.binder驅動 在android系統當中在內核當中, 負責各個用戶進程通過binder內核來進行交互的模塊驅動。

爲什麼使用binder

  1. 比Linux的跨進程通信性能好
  2. 安全 身份校驗,androi的權限模型的基礎

binder通信模型

-w868

  1. Server端在SM(ServerManager)表中註冊了一個方法
  2. Client 要想調用Server端方法,先會去SM中查詢是否存在這樣一個方法,這時候SM會返回客戶端一個代理對象方法,它是個空方法,當client端調用add方法時,它會返回給內核驅動,內核驅動接收到了代理對象方法,知道它想調用Server端的方法,會調用服務端的方法,服務端調用完成後,會返回內核驅動,SM在返回給客戶端。總結一句話:客戶端持有服務端的一個代理對象,代理對象協助驅動完成了進程通信。

AIDL、MESSAGE區別

名稱 優點 缺點 適用場景
AIDL 1.功能強大;2.支持實時通信;3.支持一對多併發通信;4.支持RPC(遠程過程調用) 1.使用複雜,需創建AIDL文件;2.需處理好線程同步問題 低併發的一對多即時通信,無RPC要求,不需要處理多線程)
Messenger 1.使用簡單,輕量級;2.支持實時通信;3.支持一對多串行通信 1.功能簡單;2.不支持RPC;3.數據通過message傳輸;4.不支持高併發場景;5.服務端想要回應客戶端,必須通過Message的replyTo把服務端的Messenger傳遞過去 一對多且有RPC需求,想在服務裏處理多線程的業務)
  • Messenger用法概述
    -w946
    server端:
    收到的請求是放在Handler的MessageQueue裏面,Handler大家都用過,它需要綁定一個Thread,然後不斷poll message執行相關操作,這個過程是同步執行的。

client端:
client端要拿到返回值,需要把client的Messenger作爲msg.replyTo參數傳遞過去,service端處理完之後,在調用客戶端的Messenger的send(Message msg)方法把返回值傳遞迴client

  • AIDL用法概述
  1. 創建 AIDL
    創建要操作的實體類,實現 Parcelable 接口,以便序列化/反序列化
    新建 aidl 文件夾,在其中創建接口 aidl 文件以及實體類的映射 aidl 文件
    Make project ,生成 Binder 的 Java 文件

  2. 服務端
    創建 Service,在其中創建上面生成的 Binder 對象實例,實現接口定義的方法
    在 onBind() 中返回

  3. 客戶端
    實現 ServiceConnection 接口,在其中拿到 AIDL 類
    bindService()
    調用 AIDL 類中定義好的操作請求
    操作請求

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章