AsyncTask завершает doInBackground() до завершения методов внутри него
Я пользуюсь 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
?
Любая помощь приветствуется:)
2 ответа
Основываясь на вашем коде, вы называете 2 разных потока.
AsynTask - это фоновый поток, который будет выполняться первым. Тогда вы позвонили в VKRequest executeWithListener
который создаст еще один поток в doInBackground()
,
Чтобы заархивировать это в одном потоке, вы должны изменить свой метод execute на executeSyncWithListener()
в VKRequest
@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;
}
Надеюсь, это поможет!
Сделайте что-то вроде этого:
@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;
}