我在一个 Android 应用程序上有一个活动,它与我的服务器启动一个同步过程。此过程消耗大量内存和处理,并且需要一些时间才能完成。
该过程完成后,会向用户显示一个 AlertDialog,显示该过程是否成功完成。
如果我离开活动前台,一切都会按预期进行。但是,有时,当我离开应用程序时,后台进程会继续其工作,但是,当我返回应用程序时,它会崩溃并出现以下错误:
android.view.WindowManager$BadTokenException: 无法添加窗口——令牌android.os.BinderProxy@4086ea48 无效;您的活动正在运行吗?
是否会因为活动被操作系统破坏而导致此错误?如果是,该进程(在另一个线程上运行)如何继续运行?而且,即使我们确认问题是由活动的破坏引起的,我该如何处理这种情况,避免崩溃并向用户显示对话框?
这是一些代码...
public class ActSincronizacao extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sincronizacao);
//Prepare so starts the process
[...]
// Defines a Handler that will be called when the process gets finished
oSocketEngine.addProgressUpdateFinishListener(new ProgressUpdateFinishListener() {
@Override
public void ProgressUpdateFinishOccurred(final ProgressUpdateFinish evt) {
//Do some processing that doesn´t envolve UI
[...]
// Process that envolves UI
runOnUiThread(new Runnable() {
public void run() {
if ((boolean)evt.getArgs().getResult()) {
//If the process gets Success
AlertDialog.Builder builder = new AlertDialog.Builder(ActSincronizacao.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("Informação");
builder.setMessage("Sincronização concluida com sucesso.");
// Defines a button handler
builder.setNeutralButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Go to another Activity
[...]
}
});
//Call the Dialog
builder.create().show();
} else {
//If something wrong hapenned
StringBuilder stb = new StringBuilder();
stb.append("Some error ocurrend while running the sync process.");
if (evt.getArgs().getMessage() != null) {
stb.append("\n\n");
stb.append(evt.getArgs().getMessage());
} else {
stb.append("\n\n");
stb.append("Try again...");
}
AlertDialog.Builder builder = new AlertDialog.Builder(ActSincronizacao.this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle("Error");
builder.setMessage(stb.toString());
builder.setNeutralButton("OK", null);
builder.create().show(); //<<<<<<<<<<<<<<<<< Crash is reported here
}
}
});
}
});
//Starts the process in backgroud (Thread)
oSocketEngine.StartCommunication(oDeviceConfig);
}
}
这是记录的完整堆栈跟踪:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4086ea48 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:532)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:200)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at PortalExecutivoSales.Android.ActSincronizacao$3$1.run(ActSincronizacao.java:138)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)