2016-08-25 56 views
1

我正在使用Vk Sdk。我创建了AsyncTask以在后台从服务器加载数据。但是,事实证明,doInBackground()在其内部的任务完成之前完成。代码如下: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创建的单独线程?

任何帮助表示赞赏:)

+1

你说得对。回调/监听器是罪魁祸首。如果请求是异步的,你不需要'AsyncTask' –

+0

我认为它的工作方式与okHttp的'Call'类似,用异步回调执行 –

+0

@ElvisChweya你对'onComplete(...)'方法有什么看法?它在主线程上运行吗?如何检查? – Marat

回答

1

此基础上你的代码,你有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; 
} 

希望这将帮助!

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

对不起,但我不太了解你的解决方案。我不想运行主线程中问题中给出的任何方法。正如你所看到的,我试图从vk的某个组下载并准备帖子。当这个过程在后台完成时,我只想显示progressBar。你能否澄清你的代码? – Marat

+0

注释行'//您的自定义回调'是'就绪'状态的要点。 – Vyacheslav

相关问题