Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用ProgressDialog等待已执行的异步任务_Android_Android Asynctask_Progressdialog_Intentservice - Fatal编程技术网

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));
        }
    }
}