Android 冷門知識點彙總:你知道哪些Android中的冷門知識?

四大組件相關:

1.啓動一個Activity,在應用進程至少須要兩個Binder線程。java

2.啓動一個launchMode爲singleTask的Activity,它並不必定會運行在新的Activity棧中。android

3.兩個不一樣應用的Activity,能夠運行在同一個Activity棧中。面試

4.同一個應用進程中的全部Activity,共享一個WindowSession。segmentfault

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攻擊等安全隱患。app

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 免費領取

或者掃描二維碼便可:

微信二維碼.png

  • 不管你如今水平怎麼樣必定要 持續學習 沒有雞湯,別人看起來的絕不費力,其實費了很大力,這四個字就是個人建議!!!!!!!!!
  • 我但願每個努力生活的IT工程師,都會獲得本身想要的,由於咱們很辛苦,咱們應得的。
相關文章
相關標籤/搜索