Android知識點基礎(chǔ)篇(二)

索引:

  1. Binder機制框全,共享內(nèi)存實現(xiàn)原理
  2. ActivityThread工作原理
  3. 嵌套滑動實現(xiàn)原理
  4. View的繪制原理,自定義View拆撼,自定義ViewGroup
  5. View闸度、SurfaceView 與 TextureView
  6. 主線程Looper.loop為什么不會造成死循環(huán)
  7. ViewPager的原理
  8. BroadcastReceiver使用總結(jié)
  9. AndroidP新特性
  10. Asset目錄與res目錄的區(qū)別

11. Binder機制蚜印,共享內(nèi)存實現(xiàn)原理

??Binder是跨進程通信(IPC)的一種解決方案窄赋。Binder中文即粘合劑楼熄,意思是粘合兩個不同的進程孝赫。從定義來講Binder是一種Android中實現(xiàn)跨進程的方式青柄;也是一種虛擬的物理設(shè)備驅(qū)動预侯,連接Service進程萎馅、Client進程和ServiceManager進程;而對于Android代碼來說飒货,Binder是一個類塘辅,實現(xiàn)了IBinder接口皆撩,將Binder機制模型以代碼的形式具體實現(xiàn)的Android中。
??一個進程空間分為用戶空間和內(nèi)和空間呻惕,進程間用戶空間數(shù)據(jù)不可共享而內(nèi)核空間是可以共享的亚脆,因為所有進程共用一個內(nèi)核空間濒持。用戶空間可以和內(nèi)核空間通過系統(tǒng)調(diào)用交互,從而實現(xiàn)內(nèi)存共享弥喉。
copy_from_user():將用戶空間的數(shù)據(jù)拷貝到內(nèi)核空間
copy_to_user():將內(nèi)核空間的數(shù)據(jù)拷貝到用戶空間

12. ActivityThread工作原理

??ActivityThread是Android應(yīng)用程序的主線程(UI線程)玛迄。理解ActivityThread類似理解Android線程管理的關(guān)鍵蓖议。
??從源碼我們可以看到ActivityThred在main函數(shù)中創(chuàng)建了Looper勒虾,這也是為什么我們再主線程使用Handler不需要自己構(gòu)建Looper的原因。然后main()通過thread.attach(false)綁定應(yīng)用進程笛钝。
??主線程的消息機制還是又Handler去執(zhí)行的愕宋。Looper的loop()方法則是起點和和興。首先通過myLooper()方法獲取Looper對象囤捻,取出Looper持有的MessageQueue。然后從MessageQueue取出Message蒜撮,如果為null淀弹,說明線程正在推出菌赖。Message不為空邑时,則調(diào)用Message的target handler對該Meeage分發(fā)浅浮,處理完畢后調(diào)用recycle()方法進行回收郁油。

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        AndroidKeyStoreProvider.install();

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

13. 嵌套滑動實現(xiàn)原理

??嵌套滑動的實現(xiàn)與傳統(tǒng)的事件分發(fā)不同,嵌套滑動式從子View傳遞給父View炒刁,從下到上的一個順序。實現(xiàn)嵌套滑動,需要我們外層父布局實現(xiàn)NestedScrollingParent肩碟,內(nèi)層子View實現(xiàn)NestedScrollingChild。
??NestedScrollingParent接口需要涉及兩個方法叙凡。首先是onStartNestedScroll(View child, View target, int nestedScrollAxes):nestedChild想要進行嵌套滾動時新啼,會調(diào)用nestedParent的這個方法。這個芳法用于指示是否支持嵌套滾動。第二個是onNestedPreScroll(View target, int dx, int dy, int[] consumed):當(dāng)我們滾動nestedChild時奈搜,nestedChild進行實際的滾動前京髓,會先調(diào)用nestParent的這個方法。nestedParent在這個方法中可以把子View想要滾動的距離消耗掉一部分或是全部消耗蒋困。
??關(guān)于原理,事實上打洼,是nestedChild的onTouchEvent()方法中會對發(fā)生的Touch事件進行判斷募疮,若為DOWN事件則會調(diào)用startNestedScroll()方法酝锅;若為MOVE事件則會調(diào)用dispatchNestedPreScroll()方法蟋字。
參考文章:十分鐘Android中的嵌套滾動機制

14. View的繪制原理鹊奖,自定義View,自定義ViewGroup

??View的繪制主要分為View的繪制和ViewGroup的繪制巡社。對于單一View的繪制气笙,在draw方法中怯晕,依次繪制背景堵第、內(nèi)容阀捅、裝飾针余。而我們經(jīng)常重寫的onDraw方法其實就是繪制內(nèi)容。而ViewGroup的繪制會掃尾復(fù)雜一些忍级,首先還是繪制自身轴咱,依次是背景朴肺、內(nèi)容戈稿、子View器瘪、裝飾橡疼。繪制子View的時候ViewGroup會遍歷子View欣除,然后挨個繪制。整個繪制自上而下历帚,樹形結(jié)構(gòu)循環(huán)滔岳。

15. View、SurfaceView 與 TextureView

??SurfaceView與TextrueView是View的子類挽牢,特點是能夠在獨立線程中繪制和渲染谱煤,在專用的GPU線程中大大提高渲染的性能。
??SurfaceView:可以通過SurfaceHolder.addCallBack在子線程中更新UI,由于SurfaceHolder的雙緩沖功能禽拔,可以是畫面更加流暢的運行刘离,但是由于holder的存在導(dǎo)致畫面更新存在間隔,并且同樣因為holder導(dǎo)致SurfaceView不能進行像View一樣setAlpha和setRotation睹栖。比較適用于類似坦克大戰(zhàn)等需要不斷告訴畫布更新的游戲硫惕。
??TextrueView:可以通過TextureView.setSurfaceTextureListener在子線程更新UI。適用于音視頻播放器或相機應(yīng)用的開發(fā)野来。

16. 主線程Looper.loop為什么不會造成死循環(huán)

??首先曼氛,結(jié)論是主線程確實阻塞了,但是主線程在初始化過程中由ActivityThread的main()方法中會創(chuàng)建一套消息循環(huán)組件包括Looper,MessageQueue,Handler,然后由MessageQueue中的next()調(diào)用底層MessageQueue,通過epoll進行阻塞,有主線程消息的時候通過發(fā)送消息激活主線程灰追。主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠团滥。因此loop的循環(huán)并不會對CPU性能有過多的消耗,也就不會造成ANR力惯。

17. ViewPager的原理

??ViewPager實現(xiàn)視圖左右滑動弄跌,原理在于創(chuàng)建了三個視圖茎匠,屏幕中間展示的是中間的視圖凯肋,而屏幕兩側(cè)隱藏著的則是預(yù)加載的視圖,當(dāng)左右滑動時,將預(yù)加載的視圖顯示出來,并且緩存當(dāng)前視圖。

18. BroadcastReceiver使用總結(jié)

??首先自定義MyBroadcastReceiver繼承BroadcastReceiver览徒,作為接收者纽什。并且注冊需要接收的Intent意圖押赊,即廣播。

public class MyBroadcastReceiver extends BroadcastReceiver {
    public static final String TAG = "MyBroadcastReceiver";
    public static int m = 1;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.w(TAG, "intent:" + intent);
        String name = intent.getStringExtra("name");
        Log.w(TAG, "name:" + name + " m=" + m);
        m++;
        
        Bundle bundle = intent.getExtras();
        
    }
}

??其次,廣播分為靜態(tài)注冊和動態(tài)注冊。當(dāng)接受有序廣播時栖疑,在權(quán)限值相同時萝快,動態(tài)注冊的接收者優(yōu)先接收廣播。

//靜態(tài)注冊
<receiver android:name=".MyBroadcastReceiver" >
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

//動態(tài)注冊
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
registerReceiver(mBroadcastReceiver, intentFilter);

??最后通過sendBoradcast(Inteng i)方法發(fā)送廣播的就可以了锨侯,如果要發(fā)送有序廣播深滚,則調(diào)用sendOrderedBroadcast(intent, receiverPermission, ...)

19. AndroidP新特性

1 室內(nèi)WIFI定位 官册。該功能API在android.net.wifi.rtt下
2 劉海平的支持。能夠通過windowInsets.getDisplayCutout()獲取一些不應(yīng)該繪制的部分屏幕击敌。
3 增加了多許多通知的支持,優(yōu)化了通知渠道。
4 新的圖片解碼類ImageDecoder
5 Android P引入了一個新的AnimatedImageDrawable類來繪制和顯示GIF和WebP動畫圖像。

20. Asset目錄與res目錄的區(qū)別

asset與res.png

** 注意: **
1 assets目錄下的資源文件不會在R.java自動生成ID寿烟,所以讀取assets目錄下的文件必須指定文件的路徑徘六。可以通過AssetManager類來訪問這些文件。比如要讀取assets目錄下的background.png:

Bitmap bgImg = getImageFromAssetFile( "background.png" );    
  
/**   
 * 從assets中讀取圖片   
 */    
private Bitmap getImageFromAssetsFile(String fileName)    
  {    
      Bitmap image = null;    
      AssetManager am = getResources().getAssets();    
      try    
      {    
          InputStream is = am.open(fileName);    
          image = BitmapFactory.decodeStream(is);    
          is.close();    
      }    
      catch (IOException e)    
      {    
          e.printStackTrace();    
      }     
      return image;    
  }    

2 如果在res/drawable目錄下建了一個名為ppt的子目錄随常,則通過 R.drawable.ppt.xxx 是獲取不到ppt目錄下的xxx文件的,會報 "R.layout.ppt cannot be resolved" 的錯誤。若在assets目錄下建立一個名為ppt的子目錄逗旁,并將background.png放入其中昙读,則代碼 Bitmap bgImg = getImageFromAssetFile( "ppt/background.png" ); 可正常運行。

End

筆者的Github Blog,希望各位大大提意見,點個star,謝謝
傳送門:WusyBlog

求互粉互贊祸穷,互贊所有文章可以私聊我呆万。哈哈,希望我們的原創(chuàng)文章能讓更多朋友看到,一起變強技矮。

筆者新開通了微信公眾號——飲水思源|wusy 計劃持續(xù)運營,每日為您分享Android干貨、原創(chuàng)文章豌习。微信掃描下方的二維碼關(guān)注我,開發(fā)學(xué)習(xí)路上不迷路。謝謝各位


飲水思源|wusy.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盹愚,更是在濱河造成了極大的恐慌憋活,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叶摄,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機移稳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來暇昂,“玉大人,你說我怎么就攤上這事泣懊♀晒危” “怎么了碎乃?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長及穗。 經(jīng)常有香客問我,道長购裙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任着帽,我火速辦了婚禮杂伟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仍翰。我一直安慰自己赫粥,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布予借。 她就那樣靜靜地躺著越平,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灵迫。 梳的紋絲不亂的頭發(fā)上秦叛,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音瀑粥,去河邊找鬼挣跋。 笑死,一個胖子當(dāng)著我的面吹牛狞换,可吹牛的內(nèi)容都是我干的避咆。 我是一名探鬼主播舟肉,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼牌借!你這毒婦竟也來了度气?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤膨报,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后适荣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體现柠,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年弛矛,在試婚紗的時候發(fā)現(xiàn)自己被綠了够吩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡丈氓,死狀恐怖周循,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情万俗,我是刑警寧澤湾笛,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站闰歪,受9級特大地震影響嚎研,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜库倘,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一临扮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧教翩,春花似錦杆勇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至路捧,卻和暖如春关霸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杰扫。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工队寇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人章姓。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓佳遣,卻偏偏與公主長得像识埋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子零渐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容