AsyncTask 在其内部方法完成之前完成 doInBackground()

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

我正在使用 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?

创建的主线程或相同的单独线程上

感谢任何帮助:)

做这样的事情:

@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' 接口的 class。

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

根据您的代码,您调用了 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;
}

希望这会有所帮助!