【发布时间】:2019-03-24 23:20:49
【问题描述】:
我使用 Glide 下载图像(每个约 4Kb)和一个带有网格布局的 recyclerview 来显示它。我将图像 url 存储在 lru 缓存中。在 onBindViewHolder() 中,我获取图像 url 并使用 Glide 显示如下:
Glide.with(mMainActivity).load(item.getPosterPath()).thumbnail(0.5f).into(holder.posterPath);
问题是,在 300 张图像后,应用程序进入内存不足异常,这是 Android 分析器信息:
这是我的 recyclerview 适配器:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_content, parent, false));
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Item item = mItems.get(position);
if (item!= null) {
holder.itemView.setTag(item);
Glide.with(mMainActivity).load(item.getPosterPath()).apply(ro).thumbnail(0.5f).into(holder.posterPath);
holder.itemView.setOnClickListener(mOnClickListener);
}
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView posterPath;
private TextView originalName;
ViewHolder(View view) {
super(view);
posterPath = itemView.findViewById(R.id.poster);
}
}
这是我的结构:
public static LruCache<Integer, Item> mItemMap = new LruCache<>(20);
物品在哪里:
public class Item {
private String mId;
private String mOriginalName;
private String mFirstAirDate;
private String mLanguage;
private String mOverview;
private String mPosterPath;
private int itemPos;
Item(String id, String originalName, String firstAirDate, String language, String posterPath, String overview, int itemPos) {
this.mId = id;
this.mOriginalName = originalName;
this.mFirstAirDate = firstAirDate;
this.mLanguage = language;
this.mOverview = overview;
this.mPosterPath = posterPath;
this.itemPos = itemPos;
}
/**
* Getters.
*/
}
我的 recyclerview 滚动适配器:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mGridLayoutManager.getItemCount();
firstVisibleItem = mGridLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
current_page++;
onLoadMore(current_page);
loading = true;
}
}
这就是我从互联网获取新数据的方式:
public void newItem() {
currentPage++;
String URL = "myurl";
RestClient.get(URL, null, mHandler);
}
mHandler 在哪里:
mHandler = new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
try {
results = (JSONArray) response.get("results");
for (int i = 0; i < results.length(); i++) {
obj = results.getJSONObject(i);
id = obj.get("id").toString();
posterPath = obj.get("poster_path").toString();
if (!posterPath.equals("null")) {
mItem.add(ItemList.createItem(id, null, null, null, POSTER_BASE_URL+posterPath, null, itemPos));
itemPos++;
}
}
notifySubscriber();
} catch (JSONException e) {
Log.d("JSON", "Error in parsing json.");
}
}
};
这是我的 RestClient:
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
所有 byte[] 分配是在何时何地进行的?
【问题讨论】:
-
显示缓存的使用情况。
-
@JeffreyBlattman 我该怎么办?
-
你需要展示更多的“东西”,我的意思是,一个屏幕截图和一条通用的线不会有太大的作用。一般来说,除非你需要,否则尽量避免使用 Activity/Fragment 作为上下文,除非你确定上下文的用途(以及谁将保留引用)。我会要求你尽最大努力用更多信息来扩展你的问题,因为它是对每个人的猜测,包括你。 :)
-
好的,谢谢!我已经更新了一些代码。
标签: android android-recyclerview out-of-memory android-glide