问题描述
我正在使用 Retrofit 从 api 返回响应.来自该响应的数据将提供给 recyclerview.将数据对象传递给回收器视图时,我在数据对象上收到空指针异常.这是因为,在设置 recyclerview 之前,应用程序不会等待返回响应.无论如何要让应用在继续之前等待响应?
I'm using Retrofit to return a response from an api. The data from that response is to be supplied to a recyclerview. I get a Null pointer exception on the data object when passing it to the recycler view. This is because, the app does not wait for the response to be returned before setting up the recyclerview. Is there anyway to have the app wait for the response before proceeding?
我已尝试提出同步改造请求,但仍然遇到同样的问题.我试过在 AsyncTask 的 onPostExecute 方法中调用 setupRecyclerView() 但这也不起作用.
I've tried making a synchronous retrofit request but I still get the same issue. I've tried calling setupRecyclerView() in the onPostExecute method of the AsyncTask but this also does not work.
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();
}
}
}
为@tmalseed 添加 ZapposAPI 以查看
Adding ZapposAPI for @tmalseed to look at
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);
}
推荐答案
找到了我的问题的解决方案.在我的原始代码中,我想等到收到 api 响应后再设置 recyclerView.但是,当您延迟设置 recyclerView 太长时间时,Android 不喜欢,所以我收到此错误:
Found the solution to my problem. In my original code I wanted to wait until I recieved an api response before setting up the recyclerView. However, Android doesn't like when you delay setting up the recyclerView for too long so I got this error:
java.lang.NullPointerException:尝试调用虚方法'布尔值android.support.v7.widget.RecyclerView$LayoutManager.onAddFocusables(android.support.v7.widget.RecyclerView,空对象引用上的 java.util.ArrayList, int, int)'
这让我回到了困境,我还没有设置 recyclerview 的响应数据.因此,在 setupRecyclerView() 中,我从 xml 导入了 recyclerview 并设置了布局管理器,但删除了创建适配器并将其添加到 recyclerview 的代码.然后我将适配器创建代码放在我的回调实现的 success() 方法中.这解决了问题!
This brought me back to the dilemna where I didn't have the response data to setup the recyclerview yet. So in setupRecyclerView(), I imported recyclerview from the xml and setup the layout manager but removed the code that created the adapter and added it to the recyclerview. Then I put the adapter creation code in the success() method of my Callback implementation. This fixed the problem!
在这里找到我的解决方案:为什么我的 android 活动因未连接适配器"而崩溃;跳过布局"但偶尔?
Found my solution here: Why my android activity is crashing with "No adapter attached; skipping layout" but sporadically?
代码如下.
公共类 SearchResultsActivity 扩展 BaseActivity {
public class SearchResultsActivity extends 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) {
}
});
}
这篇关于Android Retrofit - 在执行其他代码之前等待响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!