在开发Android应用时,我遇到了一个相当棘手的问题。该应用程序是加密货币RESTFul服务的客户端。它以最简单的形式获取一系列虚拟硬币的信息,并将它们显示在列表中,使用RecycleView组件显示。
其他时间,但它没有这样做,甚至我的调试行告诉我数据已被提取。在后一种情况下,当我拖放屏幕时,列表会显示出来(哦,是的,我将SwipeRefreshLayout添加到我的Fragment类并实现了必需品)。
该应用程序是使用MVP模式开发的,相关代码如下:
交互器类充当后端服务,通过RESTFul服务获取JSON数据,使用OKHttp lib和RxJava:
@Override
public Observable<List<Coin>> fetchCoins(){
//TODO
return Observable.fromCallable(this::getCoinList);
}
private List<Coin> getCoinList() throws IOException, JSONException {
Request request = RequestGenerator.get(Api.BIT_COINS_LIST);
String response = requestHandler.request(request);
List<Coin> coinList = CoinListingParser.parse(response);
return coinList;
}
presenter类桥接从交互器和视图类获取的数据:
@Override
public void fetchCoins() {
showLoading();
fetchSubscription = coinListingInteractor.fetchCoins().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onCoinFetchSuccess, this::onCoinFetchFailed);
}
private void onCoinFetchSuccess(List<Coin> list)
{
Log.d("CoinListing", "fetch succeeded");
if (isViewAttached())
{
coinListView.showCoins(list);
coinListView.loaded();
}
}
Fragment类实现了coinListView类,并实现了我们在presenter类中看到的showCoins方法,以便数据和GUI组件绑定 - ButterKnife用于简洁明了的代码:
public class CoinListingFragment extends Fragment implements CoinListingView,SwipeRefreshLayout.OnRefreshListener {
@Inject
CoinListingPresenter coinPresenter;
@Bind(R.id.coin_listing)
RecyclerView coinListRecycleView;
@Bind(R.id.swipe_container)
SwipeRefreshLayout mSwipeRefreshLayout;
private RecyclerView.Adapter adapter;
private List<Coin> coinList = new ArrayList<>(20);
@Override
public void showCoins(List<Coin> list) {
this.coinList.clear();
this.coinList.addAll(list);
coinListRecycleView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
}
@Override
public void onResume(){
super.onResume();
getActivity().runOnUiThread(()-> {coinPresenter.fetchCoins();});
}
}
随附的RecycleView.Adapter类如下所示:
public class CoinListingAdapter extends RecyclerView.Adapter<CoinListingAdapter.ViewHolder>{
private List<Coin> coinList;
private Context context;
private CoinListingView view;
public CoinListingAdapter(List<Coin> list, CoinListingView coinView)
{
this.coinList = list;
view = coinView;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
context = parent.getContext();
View rootView = LayoutInflater.from(context).inflate(R.layout.fragment_coin_list_grid, parent, false);
return new ViewHolder(rootView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(holder);
holder.coin = coinList.get(position);
holder.name.setText(holder.coin.getFullName()+"("+holder.coin.getName()+")");
Picasso.with(context).load(holder.coin.getImageUrl()).into(holder.img);
holder.price.setText(holder.coin.getPrice());
}
@Override
public int getItemCount() {
return coinList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
@Bind(R.id.coin_name)
public TextView name;
@Bind(R.id.image_thumb)
public ImageView img;
@Bind(R.id.coin_price)
public TextView price;
public Coin coin;
public ViewHolder(View root)
{
super(root);
ButterKnife.bind(this, root);
}
}
}
答案 0 :(得分:0)
我问的是错误的问题。问题出在RESTFul webserivce而不是客户端。服务提供商限制对其服务的访问。如果请求过于频繁,则会抛出“超出速率限制”错误,并且不会获取任何数据。