Android日常基礎知識整理(上)
摘要:
1.java char
佔兩個位元組
unicode 字符集 不是編碼,類似於ASCII碼
char 不存utf-8,而是存utf-16
utf-8 佔1~3個位元組
字串長度與字元數不相等
2.java String
最大長度
字面量,程式碼中,棧 位元組碼,65...
1.java char
佔兩個位元組 unicode 字符集 不是編碼,類似於ASCII碼 char 不存utf-8,而是存utf-16 utf-8 佔1~3個位元組 字串長度與字元數不相等
2.java String
最大長度 字面量,程式碼中,棧 位元組碼,65535 javac 65534 kt正常 讀檔案,堆 虛擬機器指令newarray Integer.MAX_VALUE 記憶體大小限制
3.java匿名內部類限制
匿名內部類有名字的,只是我們看不太懂 xx.xx.xx$1 匿名內部類的繼承結構 匿名內部類的構造方法 SAM型別 只能是介面,並且只能有一個方法
4.java方法分派
方法分給誰 靜態分派過載 編譯的時候確認,根據呼叫者的宣告型別和引數的型別 動態分派覆寫 執行的時候,根據實際的型別來分派 Groovy 根據實際的型別呼叫哪個方法
5.java 泛型
型別擦除 與C#對比 型別擦除後為Object,所以不相容基本資料型別 基本型別無法作為實參,只能引用裝箱,拆箱,需要有開銷 泛型型別無法用作方法過載 無法當做真實的型別使用 java選擇型別擦除主要考慮到了相容問題 擦除後,在一定場景下可以通過反射獲得泛型型別簽名信息 Gson Retrofit
6.onActivityResult
實際中怎麼使用 使用的時候有哪些不好的地方 能否用回撥來替代 自己設計一個方案來替代onActivityResult
7.執行緒的終止
執行緒的stop都被廢棄了 因為不安全 boolean標誌位 interrupt
8.執行緒安全
可變資源(記憶體)執行緒間共享 不變,即安全 可見,能正常處理,也會安全 原子性,每一個指令都沒有爭議 禁止指令重排序
9.ConcurrentHashMap
如何支援併發 HashTable 整個都加鎖,執行緒安全,暴力,影響效率 JDK1.5,引入段,分段鎖,給段加鎖,但hash雜湊值不均勻,會退化成HashTable JDK1.6,優化雜湊值不均勻的問題 JDK1.7,之前的16個段都直接初始化了,這個版本的段延遲初始化,用到哪個初始化哪個,並對陣列使用volatile,保證段的可見性 JDK1.8,沒有分段鎖,直接給table使用volatile
10.AR 和 ARFU
AtomicReference 和 AtomicReferenceFiledUpdater 保證原子性,作用於執行緒安全 AtomicReference 比較消耗記憶體,每個例項需要額外開闢空間儲存一些資訊 一般用在例項化較少的場景 AtomicReferenceFiledUpdater 不用額外開闢一些空間,但使用起來比較不友好,一般用於靜待物件
11.非同步
不是按照順序執行程式碼,可以是在同一執行緒 當回撥巢狀態度,就會出現回撥地獄,看起來累 引入RxJava,扁平化,解決巢狀,但要注意異常處理和取消處理的操作 Kotlin協程非同步同步化,看起來和同步產不多,還是要注意異常與取消 的處理
12.CPU架構 適配
native開發關注 mips 廢棄 x86 廢棄 armeabi相容性最好 armeabi-v7a arm64-v8a 機器根據自身對應的cpu架構,查詢對應的目錄so庫,因此提供so要提供一整套,要麼某一個架構下一個也不提供 相容也會出現一些問題 提供合適的架構(一個目錄),裡面也可以放入其他架構的so庫,使用時使用動態載入(動態識別機器的cpu架構) 線上監控,根據實際資料來判斷哪些應該使用動態載入其他架構的so庫 雲端下載 so庫體積優化 預設隱藏所有符號,只公開必要的 禁用 C++ Exception RTTI,會增加so庫大小,Android一般用不了 iostream儘量不使用,儘量使用Android log 使用gc-sections 去除無用程式碼,類似java中的proguard混淆 構建時分包,不同架構只有相應的so庫,依靠應用商城,使用者下載 時下載相應cpu架構下的ap
13.java native方法和native函式的繫結
靜態繫結命令規則對映 java包名的點替換成下劃線 native方法中需要有修飾符號 避免 C++編譯的時候把名字給搞亂了,找不到函式 動態繫結通過jni函式註冊NativeRegister 在動態 繫結之前呼叫,還是走靜態繫結方式 動態繫結後,走動態繫結方式,可以取消繫結,恢復靜態繫結方式,比較靈活 比較 函式名 動態繫結無要求,靜態繫結有命名規則 可見性 動態繫結無要求,靜態繫結需要明文符號修飾,可見 動態更換 動態繫結可以替換,靜態繫結寫死的,更換不了 呼叫效能動態繫結無需查詢,靜態繫結需要查詢,有額外開銷 開發體驗動態繫結沒啥副作用,靜態繫結重構的時候比較繁瑣 AS的支援動態繫結沒法自動關聯,靜態繫結可以關聯,可以點選跳過去,開發時方便檢視
14.jni資料傳遞
通過long型別傳遞底層物件指標給java層 注意string的幾組函式操作的區別於適用場景 GetStringUTFChars/ReleaseStringUTFChars const char *MUTF-8\0編碼成兩個位元組,避免C字元的結尾 GetStringChars/ReleaseStringChars const jchar* jni函式自動處理位元組序轉換 GetStringUTFRegion/GetStringRegion拷貝一部分字元串出來 GetStringCritical/ReleaseStringCriticalGC停掉,回收不了這一塊記憶體 注意物件陣列較大時的LocalRef超過上限的問題 注意使用DirectBuff時位元組序的問題
15.捕獲native異常
捕獲系統sig訊號來捕獲native異常 使用JniEnv的findClass 堆疊的classLoader Native執行緒繫結到jvm 有記憶體洩露問題 java物件全域性引用 獲取到的都是LocalRef,需要新建一個全域性 Native呼叫Java方法 反射 異常回調到java層
16. 其他native語言
Golang Kotlin native @CName 靜態繫結 動態繫結