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;
    }
Другие вопросы по тегам