四大組件相關:
1.啓動一個Activity,在應用進程至少需要兩個Binder線程。
2.啓動一個launchMode爲singleTask的Activity,它並不一定會運行在新的Activity棧中。
3.兩個不同應用的Activity,可以運行在同一個Activity棧中。
4.同一個應用進程中的所有Activity,共享一個WindowSession。
5.彈出一個AlertDialog,不一定需要Activity級別的Context,而且任何地方都有辦法彈出一個AlertDialog,只要是在Application的attachBaseContext之後。
下面是一個簡單的demo演示:
首先看DemoApplication,然後看Alert類:
在Application中初始化:
import android.app.Application;
public class DemoApplication extends Application {
@Override
public void onCreate() {
Alert.alertAnyWhere();
super.onCreate();
}
}
下面這個類是對AlertDialog的封裝類:
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.WindowManager;
import java.lang.reflect.Method;
public class Alert {
public static void alertDialog() {
Context mAppContext = null;
try {
Class<?> clazz = Class.forName("android.app.ActivityThread");
Method method = clazz.getDeclaredMethod("currentApplication", new Class[0]);
mAppContext = (Context) method.invoke(null, new Object[0]);
} catch (Throwable e) {
e.printStackTrace();
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(mAppContext);
builder.setTitle("Hi")
.setMessage("Hello World");
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog dialog = builder.create();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
} else {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
}
dialog.show();
}
private static Handler handler;
public static void alertAnyWhere() {
if (Looper.myLooper() == Looper.getMainLooper()) {
alertDialog();
} else {
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
handler.post(new Runnable() {
@Override
public void run() {
alertDialog();
}
});
}
}
}
6.可以通過設置Activity主題android.R.style.Theme_NoDisplay,來啓動一個不顯示的Activity,在某些需要過渡的地方很實用。
7.Activity、Service、Receiver在沒有配置intent-filter的action屬性時,exported默認爲false,配置了intent-filter的action屬性時,exported默認爲true。稍有不慎,很可能埋下越權、Intent等安全隱患。
8.當從最近使用應用列表中移除某個App時,四大組件只有Service擁有神奇的onTaskRemoved回調,但是並不一定回調,還與stopWithTask屬性等有關。
9.四大組件都運行在主線程,是因爲它們在ActityThread中(或Instrumentation)實例化;它們的生命週期也運行在主線程,是因爲通過ActivityThread.H將消息從Binder線程發送到主線程,然後執行回調。
10.TaskStackBuilder的出現基本上解決了所有構造Activity回退棧的問題。
11.ContentProvider的onCreate()方法先於Application的onCreate()方法執行,晚於Application的attachBaseContext()方法,所以在ContentProvider的onCreate()時候也是有辦法彈出一個AlertDialog的(參考5)。
12.BroadCastReceiver回調onReceive(Context context,Intent intent)中的context類型各種場景相差很大,靜態註冊的receiver回調的Context都是ReceiverRestrictedContext,動態註冊的receiver有可能是Activity或Application。
13.ServiceRecord和BroadcastRecord自身就是Binder。
14.同一個provider組件名,可能對應多個provider。
Handler、Message相關:
1.MessageQueue.addIdleHandler可以用來在線程空閒的時候,完成某些操作,比較適合那種需要在將來執行操作,卻又不知道需要指定多少延遲時間的操作。
2.Message.what儘量不要設置成0,因爲postRunnable的方式會生成Message.what爲0的消息,如果刪除了what爲0的Message,也會將runnable方式創建的Message刪掉。
3.Handler可以設置同步異步(默認是同步的),他們的區別在於異步不會被Barrier阻塞,而同步會被阻塞。
4.Handler的消息分發流程是如果Message的callback不爲空,通過callback處理,如果Handler的mCallback不爲空,通過mCallback來處理,如果前兩個都爲空,才調用handleMessage來處理。在DroidPlugin中,便是利用ActivityThread.H的這一特性,攔截了部分消息,實現Activity的插件化。
5.Java層和Native層Looper、MessageQueue的創建時序,Java層Looper—>Java層MessageQueue—>Native層NativeMessageQueue—>Native層Looper。
6.Java層通過Handler去發送消息,而Native層是通過Looper發消息。
Window、View相關:
1.硬件加速在Window級只能開不能關,View級只能關不能開。
2.自android2.3刪除MidWindow後,PhoneWindow成了Window的唯一實現類。
3.WMS管理Window的過程中涉及4個Binder,應用進程只有ViewRootImpl.W一個Binder服務端。
4.MotionEvent、KeyEvent、DragEvent等具有相似的鏈式緩存,類似Message。
5.在View的狀態保存、恢復過程中,ActionBar中所有View共享一個SparseArray容器,ContentView中所有View共享一個SparseArray容器。當前獲取焦點的View會額外存儲。
6.設置ViewTreeObserver的系列監聽方法需要確保View在attachToWindow之後,否則可能因爲add監聽和remove監聽不是作用於同一個對象而引起內存泄漏等。
Binder、IPC、進程等相關
1.可以通過文件鎖來實現進程間互斥(參考:RePlugin),在處理某些只需要單進程執行的任務時很實用。
2.Binder設計架構中,只有Binder主線程是由本進程主動創建,Binder普通線程都是由Binder驅動根據IPC通信需求被動創建。
3.oneway與非oneway,都需要等待Binder Driver的迴應消息(BR_TRANSACTION_COMPLETE),區別在於oneway不用等待BR_REPLY消息。
4.mediaserver和servicemanager的主線程都是binder線程,但system_server的主線程不是Binder線程,system_server主線程的玩法跟應用進程一樣。
5.同一個BpBinder可以註冊多個死亡回調,但Kernel只允許註冊一次死亡通知。
6.應用進程由Zygote進程孵化而來,在它真正成爲應用進程之前,系統通過拋異常的方式來清理棧幀,並反射調用ActivityThread的main方法。
7.在Binder通信的過程中,數據是從發起通信進程的用戶空間直接寫到目標進程內核空間,內核空間的數據釋放是由用戶空間控制的。
在這裏小編也分享一份自己收錄整理的Android學習PDF+架構視頻+面試文檔+源碼筆記,還有高級架構技術進階腦圖、Android開發面試專題PDF,高級進階架構資源幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習。
相信它會給大家帶來很多收穫:
上述高清技術腦圖以及配套的架構技術PDF加我wx:X1524478394 (或者技術qun:887084983)免費領取
當程序員容易,當一個優秀的程序員是需要不斷學習的,從初級程序員到高級程序員,從初級架構師到資深架構師,或者走向管理,從技術經理到技術總監,每個階段都需要掌握不同的能力。早早確定自己的職業方向,才能在工作和能力提升中甩開同齡人。
- 無論你現在水平怎麼樣一定要 持續學習 沒有ji湯,別人看起來的毫不費力,其實費了很大力,這四個字就是我的建議!!!!!!!!!
- 我希望每一個努力生活的IT工程師,都會得到自己想要的,因爲我們很辛苦,我們應得的。