Android BadTokenException 問題解決

來源:互聯網
上載者:User

標籤:android   des   blog   http   java   使用   os   io   

前言今天測試過程中發現了“android.view.WindowManager$BadTokenException”問題,這裡記錄一下解決方案。(PS:第一款應用上線了,感覺BUG還是比較多,感覺因為這個應用,能不能過試用期都是問題了,只能堅持加油了)。
問題分析這種問題其實在錯誤記錄檔中都能給出很好的提示,下面貼一下部分有用的錯誤記錄檔,如下所示:
android.view.WindowManager$BadTokenException,ViewRootImpl.java,android.view.ViewRootImpl,setView,640,android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid, is your activity running? 
通過日誌,可以知道,這種問題一般是因為在AsyncTask中的onPostExecute中執行了啟動Dialog操作,但是當前的Activity已經被銷毀了,寫一個錯誤碼複現一下該問題:
package com.example.testlibrary;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.AsyncTask;import android.os.Bundle;public class MainActivity extends Activity {private UpdateUIAsyncTask asyncTask;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);updateUIProcess();}private void updateUIProcess() {asyncTask = new UpdateUIAsyncTask();asyncTask.execute();}private class UpdateUIAsyncTask extends AsyncTask<Void, Void, Boolean> {@Overrideprotected void onPostExecute(Boolean result) {if (!isCancelled() && result) {AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).setTitle("標題").setMessage("這是內容").setPositiveButton("確定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});AlertDialog dialog = builder.create();dialog.show();}}@Overrideprotected Boolean doInBackground(Void... params) {if (!isCancelled()) {try {Thread.sleep(6000);} catch (InterruptedException e) {return false;}return true;}return true;}}}
啟動應用程式,並且在6s以內退出應用程式,返回建即可,就會發現應用程式出現了異常:
解決方案如果當前Activity已經被銷毀(無論是調用finish()或者按back、home鍵),但是Activity中的AsyncTask非同步任務並沒有結束,並且在onPostExecute中調用了alertDialog.show()就會出現:
android.view.WindowManager$BadTokenException: Unable to add window — token [email protected] is not valid; is your activity running?.
解決方案也很簡單:在alertDialog.show()執行之前,判斷當前的Activity是否已經銷毀了,可以使用android提供的isFinishing()方法。同時,在Activity中也應該增加清理AsyncTask的操作,範例程式碼如下:
package com.example.testlibrary;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.AsyncTask;import android.os.Bundle;public class MainActivity extends Activity {private UpdateUIAsyncTask asyncTask;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);updateUIProcess();}@Overrideprotected void onDestroy() {// 增加清理AysncTask操作if (asyncTask != null && asyncTask.getStatus() != AsyncTask.Status.FINISHED) {asyncTask.cancel(true);}super.onDestroy();}private void updateUIProcess() {asyncTask = new UpdateUIAsyncTask();asyncTask.execute();}private class UpdateUIAsyncTask extends AsyncTask<Void, Void, Boolean> {@Overrideprotected void onPostExecute(Boolean result) {// show dialog之前增加判斷當前Activity是否finish操作if (!isCancelled() && result && MainActivity.this != null && !MainActivity.this.isFinishing()) {AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).setTitle("標題").setMessage("這是內容").setPositiveButton("確定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});AlertDialog dialog = builder.create();dialog.show();}}@Overrideprotected Boolean doInBackground(Void... params) {if (!isCancelled()) {try {Thread.sleep(6000);} catch (InterruptedException e) {return false;}return true;}return true;}}}




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.