2015-12-17 93 views
0

我的活動名爲AllStores的列表僅包含null。我需要這個列表,因爲我想稍後填充我的ListView。問題是由於我的回調作爲最後一個執行而引起的。試圖首先執行Retrofit onResponse

爲了澄清我做了下面的截圖:

鏈接:http://i.imgur.com/bIkWjld.png

的截圖還告訴我真正想要的。爲了達到這個目的,我試了一下AsyncTask。然而,它並沒有像你在屏幕截圖中看到的那樣成功。

下面是代碼:


EDIT 2.0我已改變getSubprise()方法成爲同步和使用的AsyncTask

AllStores.java:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Response<List<Store>> subprises = new StoreService().getSubprises(); 
    System.out.println("AllStores (Activity) - subprise " + subprises); 
} 

StoreService.java :

 public Response<List<Store>> getSubprises() { 
     new LongOperation().execute(""); 
     System.out.println("getStores (StoreService.java) value "+ getStores()); 
     return getStores(); 
    } 

    private class LongOperation extends AsyncTask<String, Void, Response<List<Store>>> { 

     @Override 
     protected Response<List<Store>> doInBackground(String... params) { 
      System.out.println("doInBackground executed second"); 
      try { 
       Call<List<Store>> call = subpriseAPI.listStores(); 
       stores=call.execute(); 
       Iterator it=stores.body().iterator(); 
//    while(it.hasNext()) 
//     System.out.println(((Store)it.next()).getSTREET()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return stores; 
     } 

     @Override 
     protected void onPreExecute() { 
      //Can't put the call here because this is the main thread 
      System.out.println("onPreExecute first"); 
     } 

     @Override 
     protected void onPostExecute(Response<List<Store>> result) { 
      //Can't put the call here because this is the main thread 
      setStores(stores); 
     } 
    } 

    public Response<List<Store>> getStores() { 
     return stores; 
    } 

    public void setStores(Response<List<Store>> stores) { 
     this.stores = stores; 
    } 

但是我現在仍然得到同樣的結果見下圖:

鏈接:http://i.imgur.com/GOGFXMR.png

的截圖看起來如同從上面的截圖。

+1

你真的應該閱讀有關異步代碼和回調一些文檔。由於異步入隊調用,完整的asynctask是無用的。您的加載數據將在響應被調用時可用,所以需要更新ui。 –

+0

@Andre Classen是的,你所說的確是對的。但是我編輯了我的問題,你現在可以回答它了嗎? – superkytoz

+0

現在您已將異步入隊調用更改爲同步execeute調用。異常說明了所有'NetworkOnMainThreadException'。網絡調用必須在後臺線程中完成。例如。在asyncTask中調用'doInBackground()'。 –

回答

1

爲了從後臺線程獲得結果到主線程,我必須使用AsyncTask.get()。通過使用我可以在我的stores變量中看到一個值,而不是具有空值。

下面你可以看到我的,誰想要看到它的代碼:

​​
0

我認爲你最好讓Retrofit在其內部的HTTP執行程序內部調用內部調用。這將涉及到更改API接口是這樣的:

public interface SubpriseAPI { 
    @GET("api/locations/get") 
    List<Store> listStores(); 
} 

...和包括改造來處理反序列化到您的Store類型的任何相關配置。然而,如果你想自己調用調用,你可能會考慮託管自己的執行程序實例(或者你想運行你的工作線程),像這樣(不是這個確切的實現,但你應該明白了):

class StoreService { 
... 
private final ExecutorService executorService = Executors.newCachedThreadPool(); 
... 
public Response<List<Store>> getSubprises() { 
    executorService.submit(new Callable<List<Store>>() { 
      @Override 
      public List<Store> call() throws Exception { 
       final Call<List<Store>> call = subpriseAPI.listStores(); 

       try { 
        if(stores == null) { 
         stores = new ArrayList<>(); 
        } else { 
         stores.clear(); 
        } 

        stores.addAll(call.execute()); 

        System.out.println("stores "+ stores); 

       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }).get(); 
... 

UPDATE

我不知道你(顯然)使用改造2.我有機會嘗試了一下,這是我想出了。

這裏是相關的依賴關係,我有我的應用程序/的build.gradle:

compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' 
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' 

...這裏是我的API接口:

public interface Api { 
    @Headers("Accept: application/json") 
    @GET("/v2/567595ad0f0000ea23315d02") 
    public Call<List<Widget>> widgets(); 

} 

...這裏是一個簡單的DTO我將解開一些JSON到:

public class Widget { 
    public String value; 
} 

...最後,這裏是我的測試活動: 公共類Retrofit2TestActivity擴展AppCompatActivity {

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     final Api mockyApi = new Retrofit.Builder() 
      .baseUrl("http://www.mocky.io") 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build() 
      .create(Api.class); 

     mockyApi.widgets().enqueue(new Callback<List<Widget>>() { 
      @Override 
      public void onResponse(Response<List<Widget>> response, Retrofit retrofit) { 
       if(response.isSuccess()) { 
        Log.d(Retrofit2TestActivity.class.getName(), "## widgets.size() == " + response.body().size()); 
       } else { 
        Log.d(Retrofit2TestActivity.class.getName(), String.format("## response was NOT successful [%d]", response.code())); 
       } 
      } 

      @Override 
      public void onFailure(Throwable t) { 
       Log.d(Retrofit2TestActivity.class.getName(), String.format("## response was NOT successful [%s]", t.getMessage())); 
      } 
     }); 
    } 

} 

顯然你應該取代我WidgetStore類型。除此之外,將List<Store>作爲您活動的正常成員變量操作應該很簡單。

我希望有所幫助。

+0

我睡了之後會試試這個。現在是在我的國家的夜晚3點嘿嘿。 – superkytoz

+0

@hsi如果我使用'List listStores();'在SubpriseAPI.java中,則出現以下錯誤:'無法爲java.util.List 創建調用適配器' – superkytoz