如何通过 Activity class 和正常的 class 从 AsyncTask 获取正确的值?
How to get correct value back from AsyncTask through an Activity class and a normal class?
我有3个简化的类如下:
Main.java
public class Main extends Activity implements SomeTask.OnAsyncRequestComplete {
SomeTask someTask;
String someString = ""; //checkpoint 1
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new SomeDialog(this);
}
@Override
public void asyncResponseSomeTask(String response) {
someString = someTask.someString; //checkpoint 4
}
}
SomeDialog.java
public class SomeDialog {
public SomeDialog(Context context){
SomeTask someTask = new SomeTask(context);
someTask.execute("");
}
}
SomeTask.java
public class SomeTask extends AsyncTask<String, Integer, String> {
String someString;
OnAsyncRequestComplete caller;
Context context;
public SomeTask(Context a) {
caller = (OnAsyncRequestComplete) a;
context = a;
}
public String doInBackground(String... urls) {
doSomething();
return "";
}
private void doSomething() {
//does some stuff here and gets value from a webpage
someString = "some string"; //checkpoint 2
}
public void onPostExecute(String response) {
//checkpoint 3
caller.asyncResponseSomeTask(response);
}
}
如您所见,Main
调用 SomeDialog
并传递其上下文。 SomeDialog
调用并执行 SomeTask
,其 onPostExecute
返回给 Main
。
我有兴趣将 someString
的值从 SomeTask
返回到 Main
。
沿着检查点检查 someString
的值,我发现:
检查点 1:someString
为空 ("")
检查点 2:someString
不为空 ("some string")
检查点 3:someString
不为空 ("some string")
检查点 4:someString
为空 ("")
所以,在我看来,SomeTask
正在完美地完成它的工作(与网页通信并取回正确的数据)。在onPostExecute
中,它甚至有正确的价值。然而,当 Main
调用它的 asyncResponseSomeTask
方法时发生了一些事情并且值丢失了。也许 Main
不是在等待 SomeTask
自己完成之前完成?但如果是这样的话,那么我会在 2 或 3 之前获得检查点 4 的值(因为与网站通信确实需要一些时间),我认为这不会发生。
我的问题是:如何在 Main
中获得 someString
的正确值?
我对从 Main
调用 SomeTask
不是特别感兴趣(而不是通过 SomeDialog
)。我知道这样做确实有效并产生了正确的结果,但我想知道如何以这种方式做到这一点。
您得到空字符串是因为您从 doInBackground()
返回空字符串,它作为 onPostExecute()
的输入并最终在回调 asyncResponseSomeTask()
.
中返回
How do I get someString's correct value in Main?
public String doInBackground(String... urls) {
return doSomething();
}
private String doSomething() {
//does some stuff here and gets value from a webpage
someString = "some string"; //checkpoint 2
return someString;
}
我有3个简化的类如下:
Main.java
public class Main extends Activity implements SomeTask.OnAsyncRequestComplete {
SomeTask someTask;
String someString = ""; //checkpoint 1
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new SomeDialog(this);
}
@Override
public void asyncResponseSomeTask(String response) {
someString = someTask.someString; //checkpoint 4
}
}
SomeDialog.java
public class SomeDialog {
public SomeDialog(Context context){
SomeTask someTask = new SomeTask(context);
someTask.execute("");
}
}
SomeTask.java
public class SomeTask extends AsyncTask<String, Integer, String> {
String someString;
OnAsyncRequestComplete caller;
Context context;
public SomeTask(Context a) {
caller = (OnAsyncRequestComplete) a;
context = a;
}
public String doInBackground(String... urls) {
doSomething();
return "";
}
private void doSomething() {
//does some stuff here and gets value from a webpage
someString = "some string"; //checkpoint 2
}
public void onPostExecute(String response) {
//checkpoint 3
caller.asyncResponseSomeTask(response);
}
}
如您所见,Main
调用 SomeDialog
并传递其上下文。 SomeDialog
调用并执行 SomeTask
,其 onPostExecute
返回给 Main
。
我有兴趣将 someString
的值从 SomeTask
返回到 Main
。
沿着检查点检查 someString
的值,我发现:
检查点 1:
someString
为空 ("")检查点 2:
someString
不为空 ("some string")检查点 3:
someString
不为空 ("some string")检查点 4:
someString
为空 ("")
所以,在我看来,SomeTask
正在完美地完成它的工作(与网页通信并取回正确的数据)。在onPostExecute
中,它甚至有正确的价值。然而,当 Main
调用它的 asyncResponseSomeTask
方法时发生了一些事情并且值丢失了。也许 Main
不是在等待 SomeTask
自己完成之前完成?但如果是这样的话,那么我会在 2 或 3 之前获得检查点 4 的值(因为与网站通信确实需要一些时间),我认为这不会发生。
我的问题是:如何在 Main
中获得 someString
的正确值?
我对从 Main
调用 SomeTask
不是特别感兴趣(而不是通过 SomeDialog
)。我知道这样做确实有效并产生了正确的结果,但我想知道如何以这种方式做到这一点。
您得到空字符串是因为您从 doInBackground()
返回空字符串,它作为 onPostExecute()
的输入并最终在回调 asyncResponseSomeTask()
.
How do I get someString's correct value in Main?
public String doInBackground(String... urls) {
return doSomething();
}
private String doSomething() {
//does some stuff here and gets value from a webpage
someString = "some string"; //checkpoint 2
return someString;
}