2016-08-25 60 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

相關問題