Android 使用ProgressDialog等待已执行的异步任务
我有一个方法Android 使用ProgressDialog等待已执行的异步任务,android,android-asynctask,progressdialog,intentservice,Android,Android Asynctask,Progressdialog,Intentservice,我有一个方法public void writeEntry(Activity ctx,Entry),它获取一些数据,必须调用本机方法,这需要更长的时间才能完成。 因此,我创建了一个AsyncTask来处理ProgressDialog和本机方法。在自己的活动中测试它非常有效,在该活动中我使用了回调接口等等 在我的例子中,我有上面描述的方法,并且必须执行AsyncTask。无法在该方法中执行,因为它不会停止进一步的执行。 我需要本机方法的结果,然后才能继续执行。 是否有可能等待异步任务完成?方法wai
public void writeEntry(Activity ctx,Entry)
,它获取一些数据,必须调用本机方法,这需要更长的时间才能完成。因此,我创建了一个AsyncTask来处理ProgressDialog和本机方法。在自己的活动中测试它非常有效,在该活动中我使用了回调接口等等 在我的例子中,我有上面描述的方法,并且必须执行AsyncTask。无法在该方法中执行,因为它不会停止进一步的执行。
我需要本机方法的结果,然后才能继续执行。
是否有可能等待异步任务完成?方法
wait()
不是一个选项,因为UI线程也将等待,因此ProgressDialog的感觉将丢失
我可以从给定的参数中使用方法
runOnUiThread()
,还是启动自己的活动的唯一解决方案?因此我将尽可能多地解释
在AsyncTask中启动繁重的进程,但在AsyncTask完成后要执行的任何代码都将其放在一个单独的公共方法中。现在,完成繁重的进程调用后,在onPostExecute()
中单独创建方法
所以PSUEDO代码看起来像这样
class main extends Activity {
class Something extends AsyncTask<String, Integer, String> {
protected void onPreExecute() {
// Start your progress bar...
}
protected String doInBackground(String... params) {
// Do your heavy stuff...
return null;
}
protected void onPostExecute(String result) {
// close your progress dialog and than call method which has
// code you are wishing to execute after AsyncTask.
}
}
}
类主扩展活动{
将某个类扩展为异步任务{
受保护的void onPreExecute(){
//开始你的进度条。。。
}
受保护的字符串doInBackground(字符串…参数){
//做你的重东西。。。
返回null;
}
受保护的void onPostExecute(字符串结果){
//关闭进度对话框,然后调用具有
//您希望在异步任务后执行的代码。
}
}
}
希望这会有所帮助
祝你好运 我的第一个解决方案是在接口实现中使用回调方法参见示例 在安卓聊天室聊了一会儿之后,我听说有一个更实用的解决方案。
您可以将IntentService与PendingEvent结合使用。
通信是通过意图实现的。
如果您想使用ProgressDialog,则需要为其注册自己的活动,例如注册一个BroadcastReceiver,IntentService会在每次广播时向其发送实际状态 但我们现在就开始。
首先,我们创建活动,其中包含ProgressDialog和注册的BroadcastReceiver。BroadcastReceiver侦听有关更新和完成对话框的消息 对于活动,我们需要布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#80000000">
</LinearLayout>
现在我们要使用活动,让我们从调用它开始:
final Intent i = new Intent(parentActivity, <packages>.ProgressActivity);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_CANCELABLE, cancelable_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR, showProgress_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_STR_MESSAGE, message_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_INT_MAX, ProgressActivity.PROGRESS_DIALOG_INT_MAX_VALUE);
parentActivity.startActivity(i);
计算进度的结果应在父活动中可用,因此我们在该活动中创建PendingEvent并调用IntentService
为了接收结果,我们必须重写activityresult(int-requestCode、int-resultCode、Intent-data)的方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// Compares the requestCode with the requestCode from above
if (requestCode == ...) {
if (data.getBooleanExtra(ExampleProgressService.PROGRESS_DATA_RESULT_STATUS_BOOL, false)) {
// Calculation was success
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT);
} else
{
// Calculation is failed
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_MESSAGE);
((Exception) data.getSerializableExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_EXCEPTION));
}
}
}
这就是魔法,我希望它能帮助你。那里,哪里?我对活动描述感到困惑。请你用“there”来写名字,这样我们就知道我们在看多少不同的活动了,谢谢你在你的问题中转储相关代码:)我已经编辑了这个问题。我希望现在已经清楚了。一般来说,只有主活动调用方法writeEntry()
。我试图理解它,所以基本上您有一个wrtieEntry方法,该方法执行AsyncTask,但(writeEntry)代码继续执行。但您希望该代码等待asynctask完成它的任务。我说得对吗?是的,你说得对。我认为AsyncTask不是它的正确选择。拥有AsyncTask的整个概念是保持当前线程运行并在后台执行一些进程,我将在我的答案中给出建议;)我如何在不冻结UI线程的情况下,使用该代码片段等待AsyncTask的结果?
public class ExampleProgressService extends IntentService {
/**
* PendingIntent for callback.
*/
protected PendingIntent pi_g = null;
private static final String DEBUG_TAG = "ExampleProgressService";
/**
* Message identifier for ProgressDialog init
*/
public static final String PROGRESS_DIALOG_BROADCAST_INIT = "Dialog.Progress.Init";
/**
* Message identifier for ProgressDialog finish
*/
public static final String PROGRESS_DIALOG_BROADCAST_FINISH = "Dialog.Progress.Finish";
/**
* Message identifier for ProgressDialog update
*/
public static final String PROGRESS_DIALOG_BROADCAST_UPDATE = "Dialog.Progress.Update";
/**
* Identifier of the result for intent content
*/
public static final String PROGRESS_DATA_RESULT = "Result";
/**
* Identifier of the result error for intent content
*/
public static final String PROGRESS_DATA_RESULT_ERROR_MESSAGE = "Result.Error.Message";
/**
* Identifier of the result error exception for intent content
*/
public static final String PROGRESS_DATA_RESULT_ERROR_EXCEPTION = "Result.Error.Exception";
/**
* Identifier of the result status for intent content
*/
public static final String PROGRESS_DATA_RESULT_STATUS_BOOL = "Result.Status.boolean";
/**
* Identifier of the pending intent for intent content
*/
public static final String PROGRESS_DATA_PENDING_RESULT = "PendingResult";
public ExampleProgressService() {
super("ExampleProgressService");
}
/**
* Send the finish message.
*/
private void closeProgressActivity() {
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_FINISH);
sendBroadcast(intent);
}
/**
* Do some magic with the intent content
*/
private void extractVariablesFromIntentAndPrepare(Intent intent)
throws Exception {
pi_g = (PendingIntent) intent
.getParcelableExtra(PROGRESS_DATA_PENDING_RESULT);
if (pi_g == null) {
throw new Exception("There is no pending intent!");
}
/**
* Sends an error message.
*/
private void failed(Exception e, String message) {
Intent i = new Intent();
i.putExtra(PROGRESS_DATA_RESULT_ERROR_EXCEPTION, e);
i.putExtra(PROGRESS_DATA_RESULT_ERROR_MESSAGE, message);
send(i, false);
}
/**
* Sends the init message.
*/
private void initProgressActivity() {
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_INIT);
intent.putExtra(PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR,
multipart_g);
sendBroadcast(intent);
}
/**
* (non-Javadoc)
*
* @see android.app.IntentService#onHandleIntent(android.content.Intent)
*/
@Override
protected void onHandleIntent(Intent intent) {
extractVariablesFromIntentAndPrepare(intent);
initProgressActivity();
// do your calculation here and implements following code
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_UPDATE);
intent.putExtra(PROGRESS_DIALOG_INT_VALUE, progressValue);
sendBroadcast(intent);
// If you finished, use one of the two methods to send the result or an error
success(result);
failed(exception, optionalMessage);
}
/**
* Sends the data to the calling Activity
*/
private void send(Intent resultData, boolean status) {
resultData.putExtra(PROGRESS_DATA_RESULT_STATUS_BOOL, status);
closeProgressActivity();
try {
pi_g.send(this, Activity.RESULT_OK, resultData);
} catch (PendingIntent.CanceledException e) {
Log.e(DEBUG_TAG,
"There is something wrong with the pending intent", e);
}
}
/**
* Sends the result message.
*/
private void success(String result) {
Intent i = new Intent();
i.putExtra(PROGRESS_DATA_RESULT, result);
send(i, true);
}
}
// Some identifier for the call
int requestCode = 12345;
final Intent sI = new Intent(ExampleProgressService.PROGRESS_SERVICE_ACTION);
// Callback
sI.putExtra(ExampleProgressService.PROGRESS_DATA_PENDING_RESULT, parentActivity
.createPendingResult(requestCode, null,
PendingIntent.FLAG_CANCEL_CURRENT));
// Service start
parentActivity.startService(sI);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// Compares the requestCode with the requestCode from above
if (requestCode == ...) {
if (data.getBooleanExtra(ExampleProgressService.PROGRESS_DATA_RESULT_STATUS_BOOL, false)) {
// Calculation was success
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT);
} else
{
// Calculation is failed
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_MESSAGE);
((Exception) data.getSerializableExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_EXCEPTION));
}
}
}