bug_ _ android.view.WindowManager$BadTokenException: Unable to add window -- token

 

 

========4       關於android的一個常見錯誤:Unable to add window --token is not validhtml

android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@41791b20 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:546)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:302)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:216)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:141)
at android.view.Window$LocalWindowManager.addView(Window.java:537)
at android.app.Dialog.show(Dialog.java:278)
at android.app.AlertDialog$Builder.show(AlertDialog.java:991)
at android.widget.TextView.onTouchEvent(TextView.java:8430)
at android.view.View.dispatchTouchEvent(View.java:5553)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2027)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2027)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1762)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1397)
at android.app.Activity.dispatchTouchEvent(Activity.java:2431)
at dalvik.system.NativeStart.main(Native Method)java

1,錯誤分析:android

從錯誤信息咱們也能夠明白其緣由,此問題根本緣由就是因爲將要彈出的dialog所要依附的View已經不存在致使的。app

2,什麼地方可能照成此問題:當界面銷燬後再彈出來;或者界面跳轉時咱們的view發生改變,dialog依附的context發生變化或者界面未運行了。ide

此外,不少時候咱們須要經過一個非組件類來調用一個view類的方法來彈出dialog或Toast,這樣就須要再提供一個靜態context來建立這個dialog或者Toastpost

例如咱們在一個view中經過一個靜態類來彈出一個對話框:測試

AlertDialog.Builder builder = new AlertDialog.Builder(mContextNew);ui

固然並非全部靜態context都是能夠用來建立dialog的,例如***App().getApplication().getApplicationContext()這個context就不行,由於它並不表明哪個Activity或者View。。這樣就沒法add這個dialog。this

此view用於綁定顯示數據,咱們在其構造方法中初始化一個靜態變量mContextNew爲此view的mContext。這樣咱們就能夠經過一個靜態類來彈出對話框了,只需傳入這個靜態的context(mContextNew)就能夠了。。google

可是這個靜態的context若是隻在構造方法中初始化的話是會存在問題的,由於若是另起了一個界面其綁定數據的view也是用的這個view那麼這個靜態context就會被從新修改。。

所以當這個新的界面finish後返回到上次的界面,這個靜態的context是剛纔已經finish的view的context。所以若是仍然傳入這個靜態變量經過一個靜態類來彈出對話框就會出現上述找不到window的錯誤了。

解決辦法:

對於tab頁出現的錯誤能夠用其父類的context來彈出dialog;  對於界面已經銷燬引發的錯誤就只能判斷界面是否存在而後再彈出了;

對於利用靜態context來彈出的dialog能夠經過規避的方式來解決,好比避免出現靜態context被修改。。可是這樣就可能限制了咱們程序的功能。。

所以咱們能夠經過在bind數據時時時更新這個靜態context就能夠解決此問題了,這樣就能夠保證這個靜態的context在任何view中都是當前的界面的view的context。就不會出現找不到其父類window了。

 

===== 3     android.view.WindowManager $ BadTokenException:沒法添加窗口 - 令牌null是無效的; 爲您的活動運行?

  1. 這裏主要說的是你的android裏一個Activity發生窗體泄漏了,也就是咱們常說的內存泄漏,爲何窗體會泄漏,

    主要是你的打開一個PopupWindow(窗體)時,如圖。它沒有關閉PopupWindow(窗體),就退出這個Activity,就會發生這個錯誤,

    由於這裏就有一個順序,你要先關閉PopupWindow,再關閉Activity,這個必定的,PopupWindow(窗體)不能獨立存在。

     
  2.  

    明白這個,你就容易解決了,你先用(dismiss)關閉就行,在你的窗體須要關閉時,加上這句:

    (PopupWindow.dismiss;)PopupWindow這個是你項目裏你窗體的名字。最好作一個判斷,判斷窗體是否爲空,若是不爲空就關閉,否則有時空也關閉也會出錯。

     

========= 2          Button上點擊一下彈出一個對話框,結果遇到一個問題,android.view.WindowManager$BadTokenException: Unable to add window報了這個錯。

private void showCustomDialog() {
AlertDialog.Builder builder;
AlertDialog dialog;
LayoutInflater inflator = (LayoutInflater) LayoutInflatorActivity.this.getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflator.inflate(R.layout.dialoglayout, null);
TextView text = (TextView) view.findViewById(R.id.textview);
ImageButton imageButton = (ImageButton) view.findViewById(R.id.imageButton);
builder = new AlertDialog.Builder(this);
builder.setView(view);
dialog = builder.create();
dialog.show();
}

在這句上報錯了。由於原本個人寫法是:builder = new AlertDialog.Builder(this.getApplicationContext());

由於看了API 是new AlertDialog.Builder(Context context);想着也沒什麼語法錯誤吧。結果網上搜了一下,獲取上下文this.getApplicationContext()); 和 this的區別:

這裏的this指的固然就是Acitivity.this , 指的是這個Acitivity的上下文,而this.getApplicationContext()指的則是整個應用的上下文。

對於AlertDialog來講,是須要依賴一個View,而View是對應於Activity的。

那麼爲何會報錯呢,這裏涉及到一個生命週期的問題了。

對於一個應用Context來講,它的生命週期是整個應用程序的生命週期,而對於Activity來講,當它銷燬以後它的生命週期就結束了。


AlertDialog是屬於Acitivity的,當Activity銷燬的時候它也必須銷燬,  因此這裏咱們指定是Activity的Context。

 

==========1    android.view.WindowManager$BadTokenException: Unable to add window

android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@45f48c40 is not valid; is your activity running?
今天在寫android 的google 地圖時遇到一個問題,我在地圖上添加一個Overlay 而後想在點擊這個overlay 圖標的時候彈對話框Dialog, 按這樣的思路寫完後,測試報出了上面的異常。
代碼以下:
//這是一個繼承了ItemizedOverlay 的類中的方法。
 
@Override public boolean onTap(int i) {
// TODO Auto-generated method stub OverlayItem item = allMapOverlays.get(i);
AlertDialog.Builder dialog = new AlertDialog.Builder(context); dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet()); dialog.show(); return true; }
 
 
查資料說問題在於 context. 說不能使用 getApplicationContext(),this 所獲得的Context 必須用your_Activity.this 所獲取的Context.
而我就是用最後一種的,仍是出差。
因而我想下個人實際的運行環境,個人地圖是在tabActivity 中的,那麼獲得當前的窗體管理者應該是上一級TabActivity 全部,而非個人地圖Activity 因而我 用 getParent()所獲得的Context,運行成功。
相關文章
相關標籤/搜索