標籤:get object etc contex code create hardware nal manage
昨天做了一個demo,靜態註冊的BroadcastrReceiver在onReceive方法裡實現 alertdialog.
但是,健哥說我的這個會報錯,但是為什麼沒報錯很奇怪,我也很奇怪,今早一來我就研究了一下alertdialog的坑。
dialog 是類型同activity的應用視窗,都可以建立phonewindow執行個體。
看看dialog的建構函式:
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) { // 忽略一些代碼 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); final Window w = new PhoneWindow(mContext); mWindow = w; w.setCallback(this); w.setOnWindowDismissedCallback(this); w.setWindowManager(mWindowManager, null, null);//就是這句話。 w.setGravity(Gravity.CENTER); mListenersHandler = new ListenersHandler(this); }
setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) 第二個參數,我們設為null了。(而在activity中,這個token被設為ActivityThread傳過來的token。tockon呢是用來表示視窗的一個令牌,只有合格token才能被WMS通過添加到應用上。)
在Dialog的show方法中,
public void show() { // 忽略一些代碼 mDecor = mWindow.getDecorView(); WindowManager.LayoutParams l = mWindow.getAttributes(); // 忽略一些代碼 try { mWindowManager.addView(mDecor, l);//返回manager的時候,如果tockon不為空白會調用getSystemService(),為空白會報出異常。
mShowing = true; sendShowMessage(); } finally { } }
public Object getSystemService(@ServiceName @NonNull String name) { if (getBaseContext() == null) { throw new IllegalStateException( "System services not available to Activities before onCreate()"); }//因為一直傳過來的context的tocken if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } return super.getSystemService(name); }
系統對TYPE_APPLICATION類型的視窗,要求必需是Activity的Token,不是的話系統會拋出BadTokenException異常。Dialog 是應用視窗類別型,Token必須是Activity的Token。
AlertDialog 的context 不能是application的context