Android 使用后台应用程序中的对话框

Android 使用后台应用程序中的对话框,android,android-layout,Android,Android Layout,我有一堆异步任务来获取数据。它们通过显示对话框在执行时更新进度。有时,这会导致应用程序在后台(不可见)时崩溃。我的代码在下面调用。在不完全重新分解对话框的情况下,我可以做哪些检查来防止应用程序崩溃 它们在DownloadAsyncTask中声明,并在构造函数中传递 ProgressDialog-mDialog; 受保护的字符串mDialogMessage=“正在加载数据”; 受保护的ProgressBar程序条; doInBackground(){ if(mProgressBar!=null&&

我有一堆异步任务来获取数据。它们通过显示对话框在执行时更新进度。有时,这会导致应用程序在后台(不可见)时崩溃。我的代码在下面调用。在不完全重新分解对话框的情况下,我可以做哪些检查来防止应用程序崩溃

它们在DownloadAsyncTask中声明,并在构造函数中传递

ProgressDialog-mDialog;
受保护的字符串mDialogMessage=“正在加载数据”;
受保护的ProgressBar程序条;
doInBackground(){
if(mProgressBar!=null&&mProgressBar.getVisibility()==View.INVISIBLE){
mUIThreadHandler.post(新的Runnable(){
@凌驾
公开募捐{
mProgressBar.setVisibility(View.VISIBLE);
}
});
}else if(mDialog!=null&&!mDialog.isShowing()){
mUIThreadHandler.post(新的Runnable(){
@凌驾
公开募捐{
mDialog.setMessage(mDialogMessage);
mDialog.show();
}
});
}
}
然后
onPostExecute()

@覆盖
受保护的void onPostExecute(DefaultHandler){
onPostExecute(处理程序);
if(progBar!=null&&progBar.getVisibility()==View.VISIBLE){
progBar.setVisibility(视图不可见);
}else if(mDialog!=null&&mDialog.isShowing()){
试一试{
mDialog.discouse();
}捕获(例外e){
}   
}   
}
更新的崩溃日志:

12-20 15:19:15.802:E/AndroidRuntime(9529):
android.view.WindowManager$BadTokenException:无法添加窗口-- 代币android.os。BinderProxy@41a37908无效;你的活动是什么 跑步12-20 15:19:15.802:E/AndroidRuntime(9529):在 android.view.ViewRootImpl.setView(ViewRootImpl.java:567)12-20 15:19:15.802:E/AndroidRuntime(9529):在 addView(WindowManagerGlobal.java:246) 12-20 15:19:15.802:E/AndroidRuntime(9529):在 addView(WindowManagerImpl.java:69) 12-20 15:19:15.802:E/AndroidRuntime(9529):在 android.app.Dialog.show(Dialog.java:281)12-20 15:19:15.802: E/AndroidRuntime(9529):在 com.*.downloadsynctask$2.run(downloadsynctask.java:119)12-20 15:19:15.802:E/AndroidRuntime(9529):在 android.os.Handler.handleCallback(Handler.java:725)12-20 15:19:15.802:E/AndroidRuntime(9529):在 android.os.Handler.dispatchMessage(Handler.java:92)12-20 15:19:15.802:E/AndroidRuntime(9529):在 android.os.Looper.loop(Looper.java:137)12-20 15:19:15.802: E/AndroidRuntime(9529):在 android.app.ActivityThread.main(ActivityThread.java:5039)12-20 15:19:15.802:E/AndroidRuntime(9529):在 java.lang.reflect.Method.Invokenactive(本机方法)12-20 15:19:15.802:E/AndroidRuntime(9529):在 java.lang.reflect.Method.invoke(Method.java:511)12-20 15:19:15.802: E/AndroidRuntime(9529):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run


您正在从后台线程触摸UI。Android技术上说“不要更新”,但最好读作“不要在后台线程上与UI交互”。您的
if
语句本质上是说“如果(…)关于UI是真的,那么在将来的某个时候将此任务发布到UI线程上执行”。当您的
Runnable
在UI线程上执行时,UI的状态可能已经改变。封装整个逻辑并将其发送到要执行的UI线程可能更好。您可以将现有的两个
Runnable
组合在一起,并在一个
post
中发布,但
AsyncTask
的设计不需要直接处理程序。如果在doInBackGround中调用
publishProgress()
,它将在UI线程上向
onProgressUpdate()
成员发布一个调用。因此,更简单的方法是将
Runnable
s中的代码组合起来,然后移动到
onProgressUpdate()
方法

差不多--

使用runOnUiThread(runnable)避免崩溃:这实际上是在UI线程上运行run方法中的代码段。包装您希望在run方法中执行的所有UI操作,如下所示

因此,代码将类似于:

yourActivity.runOnUiThread(新的Runnable(){


}))

您应该检查活动是否未完成

使用以下命令:

if (!isFinishing()) {
    mDialog.show();
    }
查看此页面以了解更多说明:


请发布一个堆栈跟踪,显示异常及其来源,以便我们能够更好地告知您的错误。这种情况并不经常发生。我确实把日志文件保存在某个地方了……第119行是:@Override public void run(){mDialog.setMessage(mdilogmessage);mdilog.show();}第119行在doInBackground()内。您能将该方法连接到正在生成状态更新的异步任务吗?是的,我们能!AsyncTask基本上是在bg线程中执行的任务。所以在onPostExecute中,我们可以使用这种方法!好啊这似乎是一个更好的方法。
            @Override
            public void run() {
                // whatever UI operations..
                ..
                mDialog.setMessage(mDialogMessage);
                mDialog.show();
            }
if (!isFinishing()) {
    mDialog.show();
    }