我遇到了问题,我有一个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)
,但结果是相同的。
是否有一些选项允许我在1>} 之前执行下面的代码行?我需要在捆绑之前从数据库中检索信息,而不是颠倒。
我从几个小时就被困在这里。欢迎任何帮助。
提前致谢!
答案 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);