android - 高效地缓存、传递和查看位图 Android

标签 android caching bitmap

我有一个新闻提要,其中新闻项包含图像。每个新闻项(在 TableView 中)从服务器获取图像 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;

}

主 Activity

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(),我不确定我会在哪里使用它,因为我需要将图像保存在内存中(我本以为).

知道如何提高效率。我相信这会对很多尝试创建类似应用的人有所帮助。

最佳答案

考虑改用 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,您可以简单地下载并在您的项目中使用(其用法在上面的链接中有描述):

https://developer.android.com/intl/es/samples/DisplayingBitmaps/src/com.example.android.displayingbitmaps/util/DiskLruCache.html

也不要在 View 中保留无限量的新闻/图像。当用户滚动浏览并阅读它们时,您将不得不删除新闻项。

考虑为此使用 Recycler View (如果您希望您的应用具有 Material Design 的感觉,请考虑使用 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 View 与 Card View 相结合的更多信息: https://developer.android.com/training/material/lists-cards.html

关于android - 高效地缓存、传递和查看位图 Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31628199/

相关文章:

android - fragment 真的需要一个空的构造函数吗?

android - 我该如何着手制作这个布局?遇到这么多麻烦

caching - 禁用 EclipseLink 缓存

javascript - 本地存储中的安全浏览器端缓存

c++ - 如何仅使用直接 WinAPI 将与设备无关的位图放入 Windows 剪贴板? (没有 MFC 或其他包装器)

android - 从android中的图库获取图像时android中的java.lang.OutOfMemoryError

Android:可以在同一个任务中启动一个 Activity 的多个实例吗?

android - lint 不会失败的构建

java - Hibernate 5.4.4 中的 StandardQueryCache 替代方案是什么

bitmap - X中的XYPixmap、ZPixmap、XImage、XShmImage和Bitmap有什么区别?