AsyncTask is finishing doInBackground() before the methods inside of it are finished

545 Views Asked by At

I'm using Vk Sdk. I have created AsyncTask to load data from the server in background. However, it turns out that doInBackground() is finished before the tasks inside of it are done. The code is below:

@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;
}

I suspect that request.executeWithListener(...) is creating another thread and doing necessary work there. Therefore, AsyncTask thinks that work in his thread is finished. However, I'm not sure. There is nothing in the documentation for this method.

Another question is on which thread onComplete(...) method is running when it is called? On main or the same separate thread created by request?

Any help is appreciated :)

2

There are 2 best solutions below

0
THANN Phearum On BEST ANSWER

Base on your code, you have 2 different Threads called. AsynTask is a background thread which will execute first. Then you called VKRequest executeWithListener which will created another thread in doInBackground().

To archive this in single Thread, you should change your execute method to executeSyncWithListener() in 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;
}

Hope this will help!

2
Vyacheslav On

Do something like this:

@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;
}

where myCustomRunnable is a class that implements 'Runnable' interface.

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
                }
            });
    }

}

Or even simpler:

 @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;
    }