2015-09-09 129 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中的视图。 –

相关问题