java android.view.WindowManager$BadTokenException: 无法添加窗口 -- 令牌 android.os.BinderProxy@739b5ae 无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37042192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@739b5ae is not valid
提问by Rajubhai Rathod
I am calling another activity from main activity for download quotes in background. It's working fine sometimes, but if the user presses back button and leaves application, then tries to open the application again, sometimes the application crashes with the error below.
我正在从主要活动中调用另一个活动以在后台下载报价。有时它工作正常,但如果用户按下后退按钮并离开应用程序,然后尝试再次打开应用程序,有时应用程序会因以下错误而崩溃。
I have added logcat of error as well my class which I am calling from main activity. Whats is wrong in my code that crashes the app?
我已经添加了错误日志以及我从主要活动调用的类。我的代码有什么问题导致应用程序崩溃?
The class that I am calling from Main Activity
我从 Main Activity 调用的类
private class CheckUpdates extends AsyncTask<String, Void, Void> {
ProgressDialog mProgressDialog;
@Override
protected void onPostExecute(Void result) {
mProgressDialog.dismiss();
Log.d("DESOLF", "dismiss loading dialog");
if (json != null) {
if (jsonResultNull.equals("true")) {
AlertDialog.Builder builder = new AlertDialog.Builder(
context);
builder.setTitle("Check Updates");
builder.setMessage("There are not any updates!");
builder.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
}
});
if(SettingsActivity.tocheck==1){
builder.show();
}
} else if(SettingsActivity.tocheck==1) {
AlertDialog.Builder builder = new AlertDialog.Builder(
context);
builder.setTitle("New Data Available");
String messageTxt = "";
if (authors.length() != 0 && quotes.length() != 0) {
messageTxt = String.valueOf(authors.length())
+ " Categories and "
+ String.valueOf(quotes.length()) + " Quotes";
} else if (authors.length() != 0 && quotes.length() == 0) {
messageTxt = String.valueOf(authors.length())
+ " Categories";
} else if (authors.length() == 0 && quotes.length() != 0) {
messageTxt = String.valueOf(quotes.length())
+ " Status";
}
builder.setMessage("There are new " + messageTxt
+ " Arrived. Download?");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
Log.d("DESOLF", "start updates service");
Intent getUpdates = new Intent(context,
GetUpdatesService.class);
jsonString = json.toString();
//getUpdates.putExtra("json", json.toString());
context.startService(getUpdates);
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
}
});
builder.show();
}
else if(SettingsActivity.tocheck==0)
{
Log.d("DESOLF", "start updates service");
Intent getUpdates = new Intent(context,
GetUpdatesService.class);
jsonString = json.toString();
//getUpdates.putExtra("json", json.toString());
context.startService(getUpdates);
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Internet Connection Error");
builder.setMessage("Please connect to an internet connection!");
builder.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
builder.show();
}
}
// ------------------------------------------------------------------------
@Override
protected void onPreExecute() {
Log.d("DESOLF", "show loading dialog");
mProgressDialog = ProgressDialog.show(context, "Please Wait",
"Downloading New Status...");
mProgressDialog.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_UP)
mProgressDialog.dismiss();
return false;
}
});
}
My error logcat:
我的错误日志:
05-05 11:03:33.856: E/AndroidRuntime(19379): FATAL EXCEPTION: main
05-05 11:03:33.856: E/AndroidRuntime(19379): Process: com.example.app, PID: 19379
05-05 11:03:33.856: E/AndroidRuntime(19379): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@739b5ae is not valid; is your activity running?
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.view.ViewRootImpl.setView(ViewRootImpl.java:574)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.app.Dialog.show(Dialog.java:298)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.app.AlertDialog$Builder.show(AlertDialog.java:993)
05-05 11:03:33.856: E/AndroidRuntime(19379): at com.example.app.UpdateClass$CheckUpdates.onPostExecute(UpdateClass.java:207)
05-05 11:03:33.856: E/AndroidRuntime(19379): at com.example.app.UpdateClass$CheckUpdates.onPostExecute(UpdateClass.java:1)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.os.AsyncTask.finish(AsyncTask.java:636)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.os.AsyncTask.access0(AsyncTask.java:177)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.os.Handler.dispatchMessage(Handler.java:102)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.os.Looper.loop(Looper.java:135)
05-05 11:03:33.856: E/AndroidRuntime(19379): at android.app.ActivityThread.main(ActivityThread.java:5930)
05-05 11:03:33.856: E/AndroidRuntime(19379): at java.lang.reflect.Method.invoke(Native Method)
05-05 11:03:33.856: E/AndroidRuntime(19379): at java.lang.reflect.Method.invoke(Method.java:372)
05-05 11:03:33.856: E/AndroidRuntime(19379): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
05-05 11:03:33.856: E/AndroidRuntime(19379): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
The whole class
全班
package com.example.app;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Button;
import android.widget.Toast;
import com.example.app.R;
public class UpdateClass {
public Context context;
Button zain;
String siteUrl, updatesUrl;
DAO db;
Cursor c;
String auPictureDir;
int lastAuthor, lastQuote;
JSONArray authors = null;
JSONArray quotes = null;
JSONObject json;
static String jsonString;
String jsonResultNull = "";
private ConnectionDetector cd;
Boolean isSDPresent = android.os.Environment.getExternalStorageState()
.equals(android.os.Environment.MEDIA_MOUNTED);
// ==============================================================================
public UpdateClass(Context context) {
this.context = context;
db = new DAO(context);
db.open();
lastAuthor = db.getLastAuthor();
lastQuote = db.getLastQuote();
siteUrl = context.getResources().getString(R.string.siteUrl);
updatesUrl = siteUrl + "site/get_updates/" + String.valueOf(lastAuthor)
+ "/" + String.valueOf(lastQuote);
auPictureDir = siteUrl + "global/uploads/levels/";
}
// ==============================================================================
public void handleUpdates() {
// check first for internet
cd = new ConnectionDetector(context);
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Internet Connection Error");
builder.setMessage("Please connect to an internet connection!");
builder.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
builder.show();
} else {
new CheckUpdates().execute(new String[] { updatesUrl });
}
}
public static String getJsonString(){
return jsonString;
}
private class CheckUpdates extends AsyncTask<String, Void, Void> {
ProgressDialog mProgressDialog;
@Override
protected void onPostExecute(Void result) {
mProgressDialog.dismiss();
Log.d("DESOLF", "dismiss loading dialog");
if (json != null) {
if (jsonResultNull.equals("true")) {
AlertDialog.Builder builder = new AlertDialog.Builder(
context);
builder.setTitle("Check Updates");
builder.setMessage("There are not any updates!");
builder.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
}
});
if(SettingsActivity.tocheck==1){
builder.show();
}
} else if(SettingsActivity.tocheck==1) {
AlertDialog.Builder builder = new AlertDialog.Builder(
context);
builder.setTitle("New Data Available");
String messageTxt = "";
if (authors.length() != 0 && quotes.length() != 0) {
messageTxt = String.valueOf(authors.length())
+ " Categories and "
+ String.valueOf(quotes.length()) + " Quotes";
} else if (authors.length() != 0 && quotes.length() == 0) {
messageTxt = String.valueOf(authors.length())
+ " Categories";
} else if (authors.length() == 0 && quotes.length() != 0) {
messageTxt = String.valueOf(quotes.length())
+ " Status";
}
builder.setMessage("There are new " + messageTxt
+ " Arrived. Download?");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
Log.d("DESOLF", "start updates service");
Intent getUpdates = new Intent(context,
GetUpdatesService.class);
jsonString = json.toString();
//getUpdates.putExtra("json", json.toString());
context.startService(getUpdates);
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
}
});
builder.show();
}
else if(SettingsActivity.tocheck==0)
{
Log.d("DESOLF", "start updates service");
Intent getUpdates = new Intent(context,
GetUpdatesService.class);
jsonString = json.toString();
//getUpdates.putExtra("json", json.toString());
context.startService(getUpdates);
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Internet Connection Error");
builder.setMessage("Please connect to an internet connection!");
builder.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
if(!CheckUpdates.isFinishing()){
builder.show();
}
}
}
// ------------------------------------------------------------------------
@Override
protected void onPreExecute() {
Log.d("DESOLF", "show loading dialog");
mProgressDialog = ProgressDialog.show(context, "Please Wait",
"Downloading New Status...");
mProgressDialog.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_UP)
mProgressDialog.dismiss();
return false;
}
});
}
// ------------------------------------------------------------------------
@Override
protected Void doInBackground(String... params) {
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
// Log.e("url", params[0]);
Log.d("DESOLF", "url : params[0]");
json = jParser.getJSONFromUrl(params[0]);
Log.d("DESOLF", "json string has been downloaded");
try {
if (json != null) {
authors = json.getJSONArray("authors");
quotes = json.getJSONArray("quotes");
// Log.e("quotes", String.valueOf(quotes.length()));
if (authors.length() == 0 && quotes.length() == 0) {
jsonResultNull = "true";
}
} else {
jsonResultNull = "true";
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
采纳答案by Saritha G
Wherever you are adding builder.show(), please put the condition whether the activity is finished or not.
无论您在何处添加 builder.show(),请输入活动是否完成的条件。
Change your context reference to Activity in UpdateClass Constructor:
在 UpdateClass 构造函数中更改对 Activity 的上下文引用:
public UpdateClass(Activity context) {
//this.context also should be Activity, so please make it as a Activity Reference
this.context = context;
db = new DAO(context);
db.open();
lastAuthor = db.getLastAuthor();
lastQuote = db.getLastQuote();
siteUrl = context.getResources().getString(R.string.siteUrl);
updatesUrl = siteUrl + "site/get_updates/" + String.valueOf(lastAuthor)
+ "/" + String.valueOf(lastQuote);
auPictureDir = siteUrl + "global/uploads/levels/";
}
Like:
喜欢:
if(!context.isFinishing()){ //here activity means your activity class
builder.show();
}
回答by Ameer Faisal
Copy the whole CheckUpdates class inside MainActivity class and use MainActivity.this instead of context in CheckUpdates class at everywhere.
在 MainActivity 类中复制整个 CheckUpdates 类,并在任何地方使用 MainActivity.this 而不是 CheckUpdates 类中的上下文。