在以下代码之前执行AsyncTask

时间:2015-08-21 01:58:15

标签: java android android-asynctask

我遇到了问题,我有一个bundle我传递了一些信息。问题是我从AsyncTask检索到的信息,我需要在bundle上设置值之前执行它。

这段代码恢复了发生的事情:

String name = "";
final Bundle bundle = new Bundle();

new findCar(new OnCarListener()
{
    @Override
    public void onCarCompleted(String c) {

        synchronized (c) 
        {
            name = c;
        }
    }

    @Override
    public void onCarError(String error) {
    }
}).execute(idCar);

Log.d("AsyncTask", "AsyncTask completed");  
Log.d("AsyncTask", name);
bundle.putString(name);

AsyncTask以下的行在它之前执行。我需要它在下面的行之前执行AsyncTask

我尝试了什么:

1)正如您在上面的代码中所看到的,我创建了interface并尝试synchronize我传递的String onPostExecute()方法,其目标是在代码的其余部分之前执行,但它不起作用。

2)我看到您可以使用AsyncTask.get()阻止UI主题,但这不是我搜索的内容,因为我不知道如何AsyncTask需要很长时间才能完成其目标。

3)如果可能,我希望避免使用ProgressDialog

4)我还尝试直接在bundle内使用onCarCompleted,但它并未将值存储到bundle

5)此外,我尝试使用AsyncTask执行.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,idCar),但结果是相同的。

是否有一些选项允许我在} 之前执行下面的代码行?我需要在捆绑之前从数据库中检索信息,而不是颠倒。

我从几个小时就被困在这里。欢迎任何帮助。

提前致谢!

3 个答案:

答案 0 :(得分:1)

AsyncTask是异步的,所以当你收到数据时是未知的。 出于这个原因,你有回调。 你的第四个解决方案是正确的,但不完全。只有在回调方法中直接收到结果后,您才应该做所有需要做的事情。

private Bundle bundle;

....
bundle = new Bundle();
new findCar(new OnCarListener()
{
    @Override
    public void onCarCompleted(String c) {
        processData(c);
    }

    @Override
    public void onCarError(String error) {
    }
}).execute(idCar);

void processData(String data) {
    bundle.putString(data);
    //Do all you need then
}

使用SERIAL_EXECUTOR的executeOnExecutor方法与execute()相同,因为AsyncTasks的默认执行程序是SERIAL_EXECUTOR。

另外,为什么要同步变量?

答案 1 :(得分:1)

这就是您当前尝试失败的原因(大多数情况下,您并未真正接受手头问题的异步性):

1)正如你在上面的代码中看到的那样,我创建了一个接口并尝试将我从onPostExecute()方法传递的String与在其余部分之前执行的目标同步代码,但它不起作用。

这会因为很多原因而失败,但主要是您没有正确使用同步,并且您没有正确使用它(例如,只有一个线程在字符串上同步)。它不适合这个。

4)我也尝试在onCarCompleted中直接使用bundle,但是它没有将值存储到bundle中。

实际上,它可能确实如此。但是,无论您对bundle做什么,都可能在异步任务设置值

时完成

5)此外,我尝试使用.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,idCar)执行AsyncTask,但结果是一样的。

SERIAL_EXECUTOR按顺序执行异步任务,对您正在执行的操作没有任何影响,因为您只有一个异步任务

您应该做的是在onCarCompleted方法中添加更多逻辑。例如:

String name = "";
final Bundle bundle = new Bundle();

new findCar(new OnCarListener()
{
    @Override
    public void onCarCompleted(String name) {

        Log.d("AsyncTask", "AsyncTask completed");  
        Log.d("AsyncTask", name);
        bundle.putString(name);
        // do something with the bundle here
    }

    @Override
    public void onCarError(String error) {
    }
}).execute(idCar);

答案 2 :(得分:1)

稍微改变一下这样的方式。但我认为你应该抛出这个逻辑并更新它:尝试运行AsyncTask和onPostExecute()做它需要做的更多来完成你的工作,它更容易处理并避免“之前/之后”问题。

String name = "";
final Bundle bundle = new Bundle();
final Object lock = new Object();
new findCar(new OnCarListener(){
@Override
public void onCarCompleted(String c) {

    synchronized (c) 
    {
        name = c;
    }
lock.notify();//Unlock caller-thread
}

@Override
public void onCarError(String error) {
}
}).execute(idCar);

lock.wait();// Your current thread will be locked here, code below will not be executed until "lock.notify()" called
bundle.putString(name);