Android - 尋找Handler,main()方法

快捷鍵:

提取方法:Ctrl+Alt+M    提取全局變量:Ctrl+Alt+F  搜索類:ctrl+N

斷點調試時,遇到這個 端口號被佔用

Connected to the target VM, address: 'localhost:8610', transport: 'socket'

 

短視頻

原理:

  • 編碼與解碼:視頻壓縮成文件還原成幀圖像,h264。
  • 封裝格式
  • 硬解碼(gpu)、軟解碼(cpu)、多線程解碼
  • 關鍵幀:視頻壓縮當中比較重要的圖像幀數據

Raw文件夾:一般大文件都存放在Raw和assets文件夾

 Bundle的概念:Bundle類型的數據與Map類型的數據相似,都是以key-value的形式存儲數據的

界面跳轉:intent-fiter和Intent

Intent中文意思指“意圖”,通常Intent的隱式啓動和intent-filter連用,顯示啓動不需要intent_filter。

IOC原理:控制反轉 https://www.jianshu.com/p/f96391af0357

觀察者設計模式:觀察者與被觀察者 (以VideoView demo舉例,觀察者是界面,被觀察者就是播放器)

Handler原理圖:

 

setContentView原理:把自定義Layout加入id爲content的ViewGroup裏

findViewById:根據xml id值來映射成view對象

VideoView:對MediaPlayer的一層封裝,只支持3gp和mp4格式的播放。

清單文件:權限 、四大組件、PMS(Package Manager Service)安全檢查

VideoView全屏:videoView會根據視頻大小來改變自身的大小,所以要自定義view。

style自定義屬性的複用

Android中View和ViewGroup是組合設計模式之一(共23種)

自定義view的幾種方式:

1.繼承View完全自定義

對於繼承View類的自定義控件來說,核心的步驟分別爲尺寸測量與繪製,對應的函數爲onMeasure、onDraw,這是因爲View的子空間是視圖樹的葉子節點,不需要佈局(針對爲什麼佈局開發時有actionBar,但運行後app播放器仍然充滿屏幕)

小技巧:查找類【Ctrl+N】

TextView類中

2.繼承現有控件實現特定效果

3.繼承ViewGroup實現佈局類

這種方式主要用於自定義子視圖的排列方式時,比如下拉刷新,上拉加載等。

ViewGroup具有容器作用:因爲實現了兩個接口ViewParent和ViewManager,其中後者定義了addView及removeView等對子視圖操作的方法,重點實現onLayout方法,這個方法主要是用於子視圖的排放。

public class FrameLayout extends ViewGroup 該類下有onLayout方法


 

EXACTLY模式

該類爲精確模式。何時使用:

當我們將layout_width or layout_height 設置爲具體數值時,如100dp或是match_parent,這是系統就是調用精確模式。

AT_MOST

最大值模式,當我們將layout_width or layout_height設置爲wrap content時,系統調用的就是這個模式

此時的控件大小是隨着子控件或者內容的變化而變化,只有不超出父控件允許的最大範圍即可

UNSPECIFIED

只有在自定義控件時用到,沒有具體的測量,view自己想要多大有多大

自定義計時器:用Handler的消息機制做數據的減法操作

TextView:

自定義Shape:不自定義可以使用圖片,自定義shape用xml代碼實現

顏色色值:#ffffffff由#加八位數字或字母組成,前兩個ff爲透明度(十六進制),後面六位ffffff爲顏色代碼,採用RGB配色(十六進制)

透明度參照表:

00%=FF(不透明) 5%=F2 10%=E5 15%=D8 20%=CC
25%=BF 30%=B2 35%=A5 40%=99 45%=8c
50%=7F 55%=72 60%=66 65%=59 70%=4c
75%=3F 80%=33 85%=21 90%=19

95%=0c

100%=00 (全透明)

解決硬編碼:把代碼裏面的中文字提出到String.xml文件,一些常量可單獨提出到常量類裏面,注意未來界面整潔,維護,規範

dp px sp 之間的概念

px:像素單位        dp:安卓距離單位     sp:安卓字體大小單位

密度 ldpi mdpi hdpi xhdpi xxhdpi
密度值 120 160 240 320 480
代表分辨率 240*320 320*480 480*800 720*1280 1080*1920

當屏幕爲mdpi時,1dp=1px,換算單位爲dp=(dpi/160)px

1dp永遠都等於1sp

Bundle的概念:Bundle 類型的數據與Map類型的數據相似,都是以key-value的形式存儲數據的

界面跳轉:intent-filter和Intent

Handler原理:

線程之間的通信(子線程處理一些結果,通過handler發送到主線程,主線程通過一些方法“handleMessage()”來獲得數據)

死循環不會卡死:

這裏涉及到Linux pipe/epoll機制,簡單來說就是在主線程的messageQueue沒消息時,便阻塞在loop的queue.next()中的nativePollOnce()方法裏,此時主線程會釋放CPU資源進入休眠狀態,直到下個消息到達或者有事務發生,通過往pipe管道寫端寫入數據來喚醒主線程工作。

斷點調試

注意1!!!

//countDownTime一開始是0,需要在這裏設置傳入time
        this.countDownTime = time;

 注意2!!!當countDownTime == 0的時候,先把它取消掉,在還在進行onCreate()時,是自動取消Handler

如果說Activity還沒有走完,Handler是否還會繼續存在呢?添加cancel()

注意3!!!所以才需要手動調用一次

onCreate(),onDestory()都是系統調用的

SplashActivity添加

//界面銷燬時,回調
    @Override
    protected void onDestroy() {
        super.onDestroy();
        timer.cancel();
    }

Handler原理尋找

  

 

loop類loop()構造器

往下滑找到Looper()

創建Handler的時候,會去ThreadLocal裏面去取這個Looper,這個Looper的構造方法創建MessageQueue()

爲什麼用ThreadLocal去取,而不是新建一個呢?

這就涉及系統源碼,關於主線程Looper和MessageQueue在app剛啓動的時候就已經創建出來了,它們是在ActivityThread類

快速雙擊shift,搜索ActivityThread.java,它是一個app程序的入口,搜索main(String[] args),一般操作系統都有這麼一個main()

這裏面有一個prepareMainLooper(),就相當於創建了一個Looper,還需要調用一個Looper.loop()


 

然後拿到個MessageQueue不斷去遍歷

這是個Message類,點進去,它裏面有what,arg1,arg2這些標識

點擊CustomCountDownTimer中post(),調用sendMessageDelayed()

它把Runnable這個對象封成了一個Message,這樣就解釋通了

根據handler原理圖,我們發送一個Runable,實際上我們也封裝了一個Message到消息隊列裏面,在app程序啓動的時候,不斷去循環MessageQueue

它是把Runnable這個對象封裝在MesageQueue的callback這個成員變量裏面。

它定義了一些code,發送不同消息的一些類型,然後去回調處理這個handleMessage

Activity的生命週期:就是通過ActivityThread發送一些消息,處理不同消息類型,去調用Activity的生命週期

上傳至github

首先建立倉庫

commit

push

公司項目多人開發需要建立分支,可參考https://www.cnblogs.com/myqianlan/p/4195994.html

開發的一個分支Feature完成後,再develop合併,經過測試完後,最後master(以及還有從master拉出來hotfix進bug修改發版,拉出Release分支用於打包)

  

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