我的Android应用程序首先加载所有必要的数据,同时显示加载对话框:
// Load data in background, while updating the loading dialog.
(new AsyncTask<Void, String, Void>() {
@Override
protected Void doInBackground(Void... params) {
publishProgress(getString(R.string.loading_a));
if!(loadA())
showErrorDialogAndQuit();
publishProgress(getString(R.string.loading_b));
if(!loadB())
showErrorDialogAndQuit();
publishProgress(getString(R.string.loading_c));
if(!loadC())
showErrorDialogAndQuit();
return null;
}
protected void onProgressUpdate(String... progress) {
dialog.setMessage(progress[0]);
}
protected void onPostExecute(Void result) {
// Update the UI.
updateUI();
dialog.dismiss();
}
}).execute();
方法loadA()
,loadB()
和loadC()
可能会失败,返回false。此时,我希望显示一条错误消息,并在方法showErrorDialogAndQuit()
中退出该应用程序。
我尝试按如下方式创建它,但是在应用程序退出后似乎总是抛出错误,这与加载对话框不再有窗口有关。
public void showErrorDialogAndQuit() {
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog aDialog = new AlertDialog.Builder(MyActivity.this).setMessage("Fatal error.").setTitle("Error")
.setNeutralButton("Close", new AlertDialog.OnClickListener() {
public void onClick(final DialogInterface dialog, final int which) {
// Exit the application.
finish();
}
}).create();
aDialog.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// Disables the back button.
return true;
}
});
aDialog.show();
}
});
}
实现这一目标的最佳方法是什么?
答案 0 :(得分:0)
如果只有在成功加载A后才能执行loadB,我建议您更改代码的逻辑。您可以使用具有3种状态的最终状态机方法,其中stateA在stateA完成后被触发。
使用处理程序也可以很好地更新UI。逻辑可能如下所示:
启动threadA如下所示:
new Thread(new Runnable() {
public void run() {
loadingA();
}
}).start();
在loadingA中,你将msg发送回主体:
public void loadingA() {
...do your loading...
then to inform the main body...
Message msg = mHandlerToReceiveTheResultFromLoadingThread
.obtainMessage(MESSAGE_UPDATE_RESULT_OF_LOADING_A);
Bundle bundle = new Bundle();
bundle.putBoolean(RESULT_OK_INFO, true or false);
msg.setData(bundle);
mHandlerToReceiveTheResultFromLoadingThread
.sendMessage(msg);
}
在主体中mHandlerToReceiveTheResultFromLoadingThread
看起来像:
public final Handler mHandlerToReceiveTheResultFromLoadingThread = new Handler() {
@Override
public void handleMessage(Message msg) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(),
"-> "
+ Thread.currentThread().getStackTrace()[2]
.getMethodName() );
switch (msg.what) {
case MESSAGE_UPDATE_RESULT_OF_LOADING_A: {
boolean result_ok = msg.getData().getBoolean(RESULT_OK_INFO);
if (result_ok)
...continue with loadingB;
else
show your message that it failed and exit;
}
break;
}
}
希望这会有所帮助......
编辑:在活动的逻辑结束时调用完成:
this.myBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String msg = "Hello, I have finished and started another activity";
doOtherActivit(msg);
finish();
}
});
}
public void doOtherActivity(String msg) {
Intent i;
i = new Intent(this, OtherActivity.class);
i.putExtra("Task", msg);
startActivity(i);
}
答案 1 :(得分:0)
原来我需要做的就是在调用finish()
之前自然关闭进度对话框:
if(!loadA()) {
showErrorDialogAndQuit();
return null;
}
这可以通过创建错误对话框来实现,该对话框在另一个线程中运行,然后将null返回到AsyncTask
,使其运行onPostExecute()
并关闭进度对话框。然后,当按下错误对话框中的关闭按钮并调用finish()
时,一切都可以正常关闭。
这种方法的唯一缺点是,如果在onPostExecute()
中发生了比更新UI更重要的事情。在这种情况下,您可以修改参数类型并对其进行测试以查看要执行的操作。