2015-09-09 149 views
0

我正在使用Retrofit從api返回響應。來自該響應的數據將被提供給回收者視圖。將數據對象傳遞給回收站視圖時,我會得到一個空指針異常。這是因爲,在設置回收站視圖之前,應用程序不會等待返回響應。無論如何有這個應用程序在繼續之前等待響應?Android Retrofit - 在執行其他代碼之前等待響應?

我試過做同步改造請求,但我仍然得到同樣的問題。我已經嘗試在AsyncTask的onPostExecute方法中調用setupRecyclerView(),但這也不起作用。

public class SearchResultsActivity extends BaseActivity { 

    // UI 
    private Toolbar toolbar; 
    private SearchView searchbox; 
    private RecyclerView rvResults; 
    // Business Logic 
    private String searchQuery; 
    public Response response; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_search_results); 
     searchQuery = getSearchQuery(); 
     setupToolbar(searchQuery); 
     searchForProduct(searchQuery); 
    } 


    private void setupRecyclerView() { 
     rvResults = (RecyclerView) findViewById(R.id.rvResults); 
     rvResults.setHasFixedSize(true); 
     rvResults.setLayoutManager(new LinearLayoutManager(activityContext)); 
     ResultAdapter adapter = new ResultAdapter(response.getResults()); 
     rvResults.setAdapter(adapter); 
    } 

    private void setupToolbar(String query) { 
     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     getSupportActionBar().setTitle(""); 

    } 

    private void searchForProduct(String query) { 
     new SearchZaposTask().execute("e"); 
    } 

    private String getSearchQuery() { 
     String query = ""; 
     Intent intent = getIntent(); 
     if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 
      query = intent.getStringExtra(SearchManager.QUERY); 
     } 
     return query; 
    } 

    public class SearchZaposTask extends AsyncTask<String, Void, Response> { 

     @Override 
     protected Response doInBackground(String... params) { 

      RestAdapter retrofit = new RestAdapter.Builder() 
        .setEndpoint(Constants.BASE_URL) 
        .build(); 

      ZapposAPI api = retrofit.create(ZapposAPI.class); 
      return api.searchZappos(searchQuery); 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

     } 

     @Override 
     protected void onPostExecute(Response searchresponse) { 
      super.onPostExecute(searchresponse); 
      //Toast.makeText(activityContext,response.getResults().get(0).getProductName(),Toast.LENGTH_LONG).show(); 
      response = searchresponse; 
      setupRecyclerView(); 
     } 
    } 

} 

編輯:添加ZapposAPI爲@tmalseed看

public interface ZapposAPI { 

    @GET("/mobileapi/v1/search?") 
    Response searchZappos(@Query("term") String query); 

    @GET("/mobileapi/v1/search?") 
    void searchZapos(@Query("term") String query, Callback<Response> responseCallback); 

    @GET("https://zappos.amazon.com/mobileapi/v1/product/asin/{asin}") 
    Asin searchByAsin(@Path("asin") String asin); 
} 
+0

由於一些奇怪的原因,來電setupRecyclerView將無法正常工作。我有類似的問題,而如果我從onBacakGround()調用此相同的函數調用工作正常。專家對此問題需要更多見解!我切換到凌空,我沒有面對這個問題!如果它適合你的需求,也許你想射門射門! – k2ibegin

+0

您可以使用改裝而不使用asyncSk。這可能是更容易的任務。按照我的github回購:https://github.com/manishandroid/RetrofitAndroidExample –

+0

你可以請張貼您的ZapposAPI代碼? –

回答

0

而是做這樣的:

zapposApi.getWhatever(new Callback<List<YourPOJO>>() { 
      @Override 
      public void success(List<YourPOJO> YourPOJO, Response response) { 
       setupRecyclerView(YourPOJO); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       //handle your error 
      } 
     }); 

您的API將有可能看起來像在一些接口一行:

@GET("/user/current") 
    void getCurrentUser(Callback<YourPOJO> response); 

這種方式實際的網絡調用是在後臺完成的,回調是在UI線程上進行的。你不必爲此使用異步!

+0

我試過這個沒有運氣。我得到以下錯誤:java.lang.NullPointerException:嘗試調用虛擬方法'布爾android.support.v7.widget.RecyclerView $ LayoutManager.onAddFocusables(android.support.v7.widget.RecyclerView,java.util.ArrayList,int ,int)'在一個空對象引用上再次,我得到一個空指針異常ArrayList,應該代表我的數據。 – TBrown

0

找到解決我的問題。在我最初的代碼中,我想等到我在設置recyclerView之前收到api響應。然而,當你延遲設置了recyclerView太久因此Android不喜歡我得到這個錯誤:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$LayoutManager.onAddFocusables(android.support.v7.widget.RecyclerView, java.util.ArrayList, int, int)' on a null object reference

這使我回的dilemna,我沒有響應數據不得不安裝recyclerview然而。因此,在setupRecyclerView()中,我從xml導入了recyclerview,並設置了佈局管理器,但刪除了創建適配器的代碼並將其添加到recyclerview。然後,我將適配器創建代碼放入Callback實現的success()方法中。這解決了問題!

找到我這裏的解決方案:Why my android activity is crashing with "No adapter attached; skipping layout" but sporadically?

和代碼如下。

公共類SearchResultsActivity擴展BaseActivity {

// UI 
    private Toolbar toolbar; 
    private SearchView searchbox; 
    private RecyclerView rvResults; 

    // Business Logic 
    private String searchQuery; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_search_results); 
     searchQuery = getSearchQuery(); 
     setupToolbar(); 
     setupRecyclerView(); 
     searchForProducts(searchQuery); 
    } 

    private void setupToolbar() { 
     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     getSupportActionBar().setTitle(""); 
    } 

    private void setupRecyclerView() { 
     rvResults = (RecyclerView) findViewById(R.id.rvResults); 
     rvResults.setHasFixedSize(true); 
     rvResults.setLayoutManager(new LinearLayoutManager(activityContext)); 
    } 

    private String getSearchQuery() { 
     String query = ""; 
     Intent intent = getIntent(); 
     if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 
      query = intent.getStringExtra(SearchManager.QUERY); 
     } 
     return query; 
    } 

    private void searchForProducts(String query) { 

     RestAdapter retrofit = new RestAdapter.Builder() 
       .setEndpoint(Constants.BASE_URL) 
       .build(); 

     ZapposAPI api = retrofit.create(ZapposAPI.class); 

     api.searchZappos(query, new Callback<Response>() { 
      @Override 
      public void success(Response apiResponse, retrofit.client.Response response) { 
       ResultAdapter adapter = new ResultAdapter(apiResponse.getResults()); 
       rvResults.setAdapter(adapter); 
      } 

      @Override 
      public void failure(RetrofitError error) { 

      } 
     }); 
    } 
+0

我有同樣的問題。但我有兩個嵌套的調用。第一個電話是從黑客新聞獲取頭條新聞的ID。然後循環訪問ID並獲取物品信息並將其顯示在recylerview中。我試過你的解決方案,但仍未更新UI中的視圖。 –

相關問題