我有一个新闻Feed,其中新闻项目包含图片。每个新闻项(在表格视图中)从服务器获取图像URL,并从缓存中异步/下载图像。
我将使用一些伪代码/ Java以最简单的方式解释我的过程。
NewsItemAdapter
Map<String, Bitmap> imageCache = new HashMap<String, Bitmap>(); // init cache
String imurl = get image url from appropriate NewsObject;
Bitmap value = imageCache.get(imurl);
if (value != null) { // if bitmap is in cache
load bitmap into image view from cache;
add bitmap to NewsObject for accessing later;
}else {
execute Asynchronous bitmap download task;
}
异步位图下载任务(scaleDownBitmap()
的原因是由于我得到的OutOfMemory错误)
doinBackground(Void...params){
myBitmap = download bitmap from imurl;
imageCache.put(imurl, scaleDownBitmap(myBitmap)); // put bitmap into cache
return scaleDownBitmap(myBitmap);
}
onPostExecute(Bitmap result){
load result into image view;
}
MainActivity
setOnNewsItemClickListener{
intent = get intent to mainNewsScreen; //after you click on news item
intent.putExta("newsBitmap", bitmap from NewsObject); // set in NewsItemAdapter
startActivity(intent);
}
MainNewsScreen
onCreate(){
load bitmap from intent extras into image view;
}
我的主要问题是,如果我删除找到的scaleDownBitmap()
方法here,我会收到OutOfMemory错误。
但是我失去了很多图像质量。你可以看到我还没有使用bitmap.recycle()
,我不完全确定我在哪里使用它,因为我需要将图像保存在内存中(我原以为)
任何想法如何提高效率。我确信这会对很多尝试创建类似应用的人有所帮助。
答案 0 :(得分:1)
考虑使用lrucache,并将图像存储在磁盘缓存之外时将其存储在磁盘上。
此处解释了最佳做法: http://developer.android.com/intl/es/training/displaying-bitmaps/cache-bitmap.html
将此代码视为一个想法,其中一些是从上面的链接复制的:
...
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
@Override
protected void entryRemoved (boolean evicted, K key, V oldValue, V newValue) {
// Save your entry to disc instead
}
};
Google制作了一个DiscLruCache,您可以在项目中轻松下载和使用(其用法在上面的链接中有描述):
也不要在视图中保留无限量的新闻/图像。当用户滚动浏览新闻项目并阅读它们时,您将不得不删除新闻项目。
考虑使用Recycler视图(如果您想要对应用程序使用Material设计感觉,请使用Cards): https://developer.android.com/intl/es/reference/android/support/v7/widget/RecyclerView.html
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager)
牌: https://developer.android.com/intl/es/reference/android/support/v7/widget/CardView.html
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="200dp"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v7.widget.CardView>
有关将Recycler视图与Card视图相结合的更多信息: https://developer.android.com/training/material/lists-cards.html