Android 相關重難點知識整理
阿新 • • 發佈:2019-02-20
集合
- 對
HashMap
進行排序:HashMap
本身無序,但其子類LinkedHashMap
使用連結串列結構,實現了有序。通過HashMap#entrySet()
方法可以將Map
轉為Set<Entry>
,再在ArrayList
的建構函式中可以傳入Collections
,正好Set
和List
的父類就是Collections
,這樣就可以呼叫Collections.sort(list, comparator)
進行排序了。排序好後,使用for
遍歷加入LinkedHashMap
。
引用型別
引用型別
強引用
String str
軟引用
SoftReference<String> soft = new SoftReference<String>(str);
弱引用
WeakReference<String> wek = new WeakReference<String>(str);
虛引用
PhantomReference
// 注意 String str = "abc"; // 常量池中 String str = new String("abc"); // 堆記憶體中
物件可及性
強可及物件: 除非虛擬機器OOM
,否則永遠不會被回收
軟可及物件: 系統記憶體不足時,被回收
弱可及物件: 當系統GC
執行緒池
控制一個方法的併發數量限制
方法一,使用訊號量
Semaphore
訊號量,建構函式傳入允許個數。
Semaphore#acquire()
取得鎖,Semaphore#release()
釋放鎖。方法二,使用執行緒池
Excutors.newFixedThreadPool(num);
手動實現執行緒池
new ThreadPoolExecutor(
int corePoolSize, // 核心池大小: 建議 CPU 個數+1
int maximumPoolSize, // 執行緒池最大容量
long keepAliveTime, // 任務執行完畢後釋放延時
TimeUnit unit, // 時間的單位
BlockingQueue<Runnable> workQueue, // 工作佇列
ThreadFactory threadFactory, // 將 Runnable 包裝成執行緒的工廠
RejectedExecutionHandler handler)
- 執行緒數總大小為 最大池大小(Thread)+佇列(Runnable)
- 介面
BlockingQueue
是單端佇列,BlockingDueue
是雙端佇列。對於單端佇列,其子類有Array
和Linked
等,對於此處頻繁增刪的需求,使用LinkedBlockingQueue
更佳。 - 對於
i++
,要使用執行緒安全的AtomInteger#getAndIncrement()
方法
IOC (DI)
- IOC(DI) 概念
Inverse Of Controller,控制反轉; Dependency Inject 依賴注入。 - ViewUtils框架,XUtils中的四大部分之一,使用到就是 IOC
- 自定義註解
- Target,註解類作用的物件,如FILED、METHOD等
- Retention,生命週期,SOURCE(原始碼中存在,編譯成位元組碼被清除)、CLASS(位元組碼中存在,執行時被清除)、RUNTIME(執行期執行期有效,會被載入到虛擬機器中)
- 定義體中,
value
作為預設變數名,如@XXX("abc")
- 反射
getFiled()
只能獲取public
修飾的欄位,通常使用getDeclaredFileld()
獲取申明的欄位- 設定欄位的值先通過
DeclaredFiled#setAccessible(true)
暴力取得許可權,再通過DeclaredField#set(user, name)
設定
Handler 機制
Handler
通常用於子執行緒給主執行緒傳送訊息Looper.prepare()
,建立Looper
,建立MessageQueue
,通過ThreadLocal
將Looper
與主執行緒繫結new Handler()
,從ThreadLocal
中取得Looper
,從Looper
中取得MessageQueue
的引用handler#sendMeessage()
,訊息中新增msg.target=this
,然後放入MessageQueue
Looper#loop()
,迴圈取訊息池,呼叫dispatchMessage()
Looper
需要呼叫Looper#quit()
終止
Fragment
Fragment
切換使用Fragment#hide()
和Fragment#show()
效率最高手動實現回退棧
- 每次替換
Fragment
的時候新增到List
if(list.contains(fragment)){ list.remove(fragment); list.add(fragment); }else { list.add(fragment); }
- 監聽返回按鈕
if(list.size() > 1){ list.remove(list.size()-1); transcation .hide(...) .show(list.get(list.size()-1)) .commit(); }else { finish(); }
- 每次替換
圖片處理
- ImageLoader
年限久,使用者量大 - Glide
官方推薦使用,功能強大 - Picasso
熱門,受歡迎 - Fresco
三級快取,不能使用原生的控制元件
序列化
Serializable
是Java SE
實現的用於物件序列化的介面,Parcelable
是Android
推出的用於序列化的介面。Serializable
實現更簡單,但效能不如Parcelable
transient
關鍵字用於保留欄位不被序列化
Activity 儲存
onSaveInstanceState()
是會在onStop()
前呼叫,用於儲存Activity
的狀態- 呼叫時機: 橫豎屏切換、HOME鍵後臺等,但按返回鍵將不會呼叫
自定義許可權
- 在清單檔案中
Activity
可設定屬性permission
來自定義啟用該活動所需要的許可權,可以任意命名 - 自定義許可權在使用的時候要先宣告再使用:
// 宣告許可權
<permission android:name="com.xxx.xxx.AAA" />
// 使用許可權
<use-permission android:name="com.xxx.xxx.AAA" />
- 四大元件都是可以宣告自定義許可權的
- 在廣播接收者中,呼叫
sendBroadcast(intent, String permission)
指定許可權,但仍然需要在清單檔案中申明與使用,廣播的自定義許可權主要用於友方相互喚醒
Service
startService()
方式啟動,Service
就一直在後臺執行,與其他元件的生命週期無關,bindService()
方式啟動,Activity
銷燬時該Service
也同時銷燬IntentService
用於執行較耗時的後臺任務,執行完成後自動銷燬
7.0 新特性
JIT
編譯器: 安裝速度提升75%
,並減少50%
的應用程式編譯程式碼,並在同等CPU
效能從30%
提高到600%
,使用JIT
可以讓使用者安裝程式、執行應用更快。Vulkan API
:Open GL
的下一個版本,Android 7.0
將支援相關API
- 多視窗模式: 可以分屏開多個多視窗
- 可回覆通知: 通過
Notifiction.builder
中addAction()
可以設定回覆 - 目錄訪問許可權: 使用
StorageManager
訪問目錄,,,它將動態申請許可權,而不需要在清單檔案中申明許可權 - 流量節省程式: 系統增加了一個全域性的流量節省工具
ICU4J API
支援: 系統內建了該免費開源Unicode
工具庫,不需要再在應用中整合Direct Boot
: 新的系統中應用可以申請在開機未解鎖的情況下直接啟動,比如微信、第三方的鬧鐘等VR
使用: 支援VR
應用程式編寫,使用com.google.vr.sdk.widgets.pano.VrPanoramaView
控制元件和com.google.vr.sdk.widgets.pano.VrVideView
分別顯示圖片和視訊