android.util.LruCache

本书介绍如何调优Android应用,涵盖Java、NDK优化技巧,内存高效利用,节省电量,多线程运用,基准测试等内容。重点介绍了LruCache类及其在不同Android版本中的使用策略。
  

本文所属图书 > Android应用性能优化

本书主要介绍如何调优Android 应用,以使应用更健壮并提高其执行速度。内容包括用Java、NDK 优化应用,充分利用内存以使性能最大化,尽最大可能节省电量,何时及如何使用多线程,如何使用基准问题测试代码,如...  立即去当当网订购

值得一提的另一个类是android.util.LruCache<K, V>,这个类是Android 3.1(代号 Honeycomb MR1)引入的,可以在创建时定义缓存的最大长度。另外,还可以通过覆写sizeof()方法改变每个缓存条目计算大小的方式。因为android.util.LruCache只能在Android 3.1及更高版本上使用,如果针对版本低于3.1的Android设备,则仍然必须使用不同的类来实现自己的应用缓存。由于目前的Android 3.1设备占有率不高,这种情况很有可能出现。替代方案是继承java.util.LinkedHashMap覆写removeEldestEntry。LRU(Least Recently Used)缓存先丢弃最近最少使用的项目。在某些应用中,可能需要完全相反的策略,即丢弃缓存中最近最多使用的项目。Android现在没有这种MruCache类,考虑到MRU缓存不常用,这并不奇怪。

当然,缓存是用来存储信息而不是计算结果的。通常,缓存被用来存储下载数据(如图片),但仍需严格控制使用量。例如,覆写LruCache的的sizeof方法不能简单地以限制缓存中的条目数为准则。尽管这里简要地讨论了LRU和MRU策略,你仍可以在缓存中使用不同的替代策略,最大限度地提高缓存命中率。例如,缓存可以先丢弃那些重建开销很小的项目,或者干脆随机丢弃项目。请以务实的态度设计缓存。简单的替换策略(如LRU)可以产生很好的效果,把手上资源留给更重要的问题。

我们用了几个不同的技术优化斐波那契数列的计算。虽然每种技术都有其优点,却没有一个实现是最佳选择。往往最好的结果是结合多种不同的技术,而不是只依赖于其中之一。例如,更快的实现可以使用预计算、缓存机制,甚至采用不同的公式。(提示:当n是4的倍数,会发生什么?)怎样在100毫秒内计算出FInteger.MAX_VALUE?

前端布局页面代码:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".L"> <!-- 网络图片显示控件 --> <com.android.volley.toolbox.NetworkImageView android:id="@+id/networkImageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:adjustViewBounds="true" /> <!-- 加载按钮 --> <Button android:id="@+id/buttonLoad" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="加载网络图片" /> </LinearLayout> Java代码:package com.example.shopapp; import android.graphics.Bitmap; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.NetworkImageView; import com.android.volley.toolbox.Volley; import android.util.LruCache; public class L extends AppCompatActivity { private RequestQueue requestQueue; private ImageLoader imageLoader; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化RequestQueue requestQueue = Volley.newRequestQueue(this); // 创建ImageLoader实例 imageLoader = new ImageLoader(requestQueue, new BitmapCache()); // 获取NetworkImageView和Button实例 final NetworkImageView networkImageView = findViewById(R.id.networkImageView); Button buttonLoad = findViewById(R.id.buttonLoad); // 设置默认图片和错误图片 networkImageView.setDefaultImageResId(android.R.drawable.ic_menu_gallery); networkImageView.setErrorImageResId(android.R.drawable.ic_dialog_alert); // 定义图片URL final String imageUrl = "https://img.shetu66.com/2023/04/25/1682410853619598.png"; // 设置按钮点击事件 buttonLoad.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { networkImageView.setImageUrl(imageUrl, imageLoader); Toast.makeText(L.this, "正在加载图片...", Toast.LENGTH_SHORT).show(); } }); } // 自定义Bitmap缓存类 private static class BitmapCache implements ImageLoader.ImageCache { private final LruCache<String, Bitmap> cache; public BitmapCache() { int maxSize = 10 * 1024 * 1024; // 10MB缓存大小 cache = new LruCache<String, Bitmap>(maxSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getRowBytes() * bitmap.getHeight(); // 计算图片大小[^1] } }; } @Override public Bitmap getBitmap(String url) { return cache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { cache.put(url, bitmap); } } }
06-04
08-27 19:27:23.877637 19900 16919 E AndroidRuntime: FATAL EXCEPTION: ForkJoinPool.commonPool-worker-1 Process: com.cnn.mobile.android.phone, PID: 19900 java.lang.IllegalStateException: Can't copy a recycled bitmap at android.graphics.Bitmap.checkRecycled(Bitmap.java:461) at android.graphics.Bitmap.createAshmemBitmap(Bitmap.java:779) at android.graphics.Bitmap.asShared(Bitmap.java:804) at android.widget.RemoteViews$BitmapCache.getBitmapId(RemoteViews.java:2548) at android.widget.RemoteViews$BitmapReflectionAction.setHierarchyRootData(RemoteViews.java:2636) at android.widget.RemoteViews.configureDescendantsAsChildren(RemoteViews.java:6515) at android.widget.RemoteViews.configureAsChild(RemoteViews.java:6492) at android.widget.RemoteViews.-$$Nest$mconfigureAsChild(Unknown Source:0) at android.widget.RemoteViews$RemoteCollectionItems.setHierarchyRootData(RemoteViews.java:9660) at android.widget.RemoteViews$RemoteCollectionItems.<init>(RemoteViews.java:9619) at android.widget.RemoteViews$RemoteCollectionItems$Builder.build(RemoteViews.java:9967) at android.widget.RemoteViewsService$RemoteViewsFactory.getRemoteCollectionItems(RemoteViewsService.java:167) at android.widget.RemoteViewsService$RemoteViewsFactoryAdapter.getRemoteCollectionItems(RemoteViewsService.java:285) at android.widget.RemoteViews$RemoteCollectionCache.lambda$getItemsFutureFromIntentWithTimeout$2(RemoteViews.java:1705) at android.widget.RemoteViews$RemoteCollectionCache$$ExternalSyntheticLambda0.accept(D8$$SyntheticClass:0) at android.appwidget.AppWidgetManager$ServiceCollectionCache$ConnectionTask.lambda$handleNext$0(AppWidgetManager.java:1763) at android.appwidget.AppWidgetManager$ServiceCollectionCache$ConnectionTask.$r8$lambda$Vx3DOS7p-JdYlu3LYsONTQNRSZ0(Unknown Source:0) at android.appwidget.AppWidgetManager$ServiceCollectionCache$ConnectionTask$$ExternalSyntheticLambda3.run(D8$$SyntheticClass:0) at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1428) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:391) at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1322) at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1858) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1823) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
最新发布
09-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值