我正在使用Vk Sdk。我创建了AsyncTask来在后台从服务器加载数据。但是,事实证明doInBackground()
在其内部的任务完成之前就已完成。代码如下:
@Override
protected Void doInBackground(Void... params) {
Log.v(TAG, "Before Loading in Background");
VKRequest request = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID, "-100177655", VKApiConst.OFFSET, "2"));
request.executeWithListener(new VKRequest.VKRequestListener() {
@Override
public void onComplete(VKResponse response) {
super.onComplete(response);
String jsonData = response.responseString;
Log.v(TAG, "json is ready");
try {
Log.v(TAG, "before parsing");
parsePostsData(jsonData);
Log.v(TAG, "after parsing");
} catch (JSONException e) {
Log.v(TAG, "EXCEPTION is thrown");
e.printStackTrace();
}
}
});
Log.v(TAG, "Finished Background Tasks");
return null;
}
我怀疑request.executeWithListener(...)
正在创建另一个线程并在那里做必要的工作。因此,AsyncTask认为他的线程中的工作已经完成。但是,我不确定。该方法的文档中没有任何内容。
另一个问题是调用哪个线程onComplete(...)
方法正在运行?在由request
创建的主要或同一个单独的线程上?
感谢任何帮助:)
答案 0 :(得分:1)
根据您的代码,您有2个不同的线程被调用。
AsynTask是一个首先执行的后台线程。然后你调用了VKRequest executeWithListener
,它将在doInBackground()
中创建另一个线程。
要在单个线程中存档,您应该将执行方法更改为VKRequest中的executeSyncWithListener()
@Override
protected Void doInBackground(Void... params) {
Log.v(TAG, "Before Loading in Background");
VKRequest request = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID, "-100177655", VKApiConst.OFFSET, "2"));
request.executeSyncWithListener(new VKRequest.VKRequestListener() {
@Override
public void onComplete(VKResponse response) {
super.onComplete(response);
String jsonData = response.responseString;
Log.v(TAG, "json is ready");
try {
Log.v(TAG, "before parsing");
parsePostsData(jsonData);
Log.v(TAG, "after parsing");
} catch (JSONException e) {
Log.v(TAG, "EXCEPTION is thrown");
e.printStackTrace();
}
}
});
Log.v(TAG, "Finished Background Tasks");
return null;
}
希望这会有所帮助!
答案 1 :(得分:0)
做这样的事情:
@Override
protected Void doInBackground(Void... params) {
Log.v(TAG, "Before Loading in Background");
VKRequest request = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID, "-100177655", VKApiConst.OFFSET, "2"));
request.executeWithListener(new VKRequest.VKRequestListener() {
@Override
public void onComplete(VKResponse response) {
super.onComplete(response);
String jsonData = response.responseString;
Log.v(TAG, "json is ready");
// YOUR CUSTOM CALLBACK
new Thread(new myCustomRunnable(jsonData)).start();
try {
Log.v(TAG, "before parsing");
parsePostsData(jsonData);
Log.v(TAG, "after parsing");
} catch (JSONException e) {
Log.v(TAG, "EXCEPTION is thrown");
e.printStackTrace();
}
}
});
Log.v(TAG, "Finished Background Tasks");
return null;
}
其中myCustomRunnable
是一个实现'Runnable'接口的类。
public class myCustomRunnable implements Runnable{
private String msg ="";
public OToast(String msg) {
this.msg = msg;
}
@Override
public void run() {
//here do anything you want
Log.v("mylog",msg);
//or even execute code in main thread:
runOnUiThread(new Runnable() {
@Override
public void run() {
//your code
}
});
}
}
甚至更简单:
@Override
protected Void doInBackground(Void... params) {
Log.v(TAG, "Before Loading in Background");
VKRequest request = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID, "-100177655", VKApiConst.OFFSET, "2"));
request.executeWithListener(new VKRequest.VKRequestListener() {
@Override
public void onComplete(VKResponse response) {
super.onComplete(response);
String jsonData = response.responseString;
Log.v(TAG, "json is ready");
// EXECUTE CODE IN MAIN UI THREAD:
final String final_json = jsonData;
runOnUiThread(new Runnable() {
@Override
public void run() {
//your code
textview.setText(final_json);
}
});
try {
Log.v(TAG, "before parsing");
parsePostsData(jsonData);
Log.v(TAG, "after parsing");
} catch (JSONException e) {
Log.v(TAG, "EXCEPTION is thrown");
e.printStackTrace();
}
}
});
Log.v(TAG, "Finished Background Tasks");
return null;
}