1.提供高响应和快速Android应用程序的编程技巧
1.1。为什么要小心使用Android资源
Android设备的功耗低于标准台式机或笔记本电脑。因此,您必须小心内存消耗。
特别是在Android 5.0之前的Android设备上,您希望避免触发Java虚拟机的垃圾收集器。这会导致Android运行时冻结约200毫秒。如果用户例如向下滚动列表,则这可能是显着的延迟。
1.2。避免不必要的对象分配
避免创建不必要的物体,尤其是在昂贵的地方 尽可能重用对象。创建不必要的对象会更频繁地触发垃圾回收,这应该避免。
例如,避免在循环或onDraw()
自定义视图的方法中创建对象。
1.3。使用高效的数据结构
Android提供了几种Sparse*Array
类的实现。请考虑以下代码。
Map<Integer, String> map = new HashMap<Integer, String>();
使用此代码会导致Integer创建不必要的对象。
Android提供的数据结构更有效地将值映射到其他对象。如果可能的话,使用这些对象,就像使用HashMap一样,它们避免了对象的创建。对象创建可能很昂贵,应该避免以减少垃圾收集器运行所需的次数。
66.png要改进上面的示例,请使用以下数据结构。
SparseArray<String> map = new SparseArray<String>();
map.put(1, "Hello");
2.处理位图
如果以全尺寸加载,位图可以分配大量内存。建议将所需大小的位图加载到内存中。假设您有一个以100x100 dp显示图像的应用程序,您应该以这个大小加载图像。
一种常见的方法是首先测量位图,而不是通过传递给它的标志加载它BitmapFactory
。
// instruct BitmapFactory to only the bounds and type of the image
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
// get width and height
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
// type of the image
String imageType = options.outMimeType;
之后,您可以加载图像的缩放版本。Android非常适合以2的幂来缩放图像。您可以使用以下方法(来自官方Android文档)以2为基础计算比例因子。
public static Bitmap decodeBitmapWithGiveSizeFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
此方法可用于将图像分配给视图,如以下示例所示。
viewWidth = imageView.getWidth();
viewHeight = imageView.getHeight();
imageView.
imageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, viewWidth, viewHeight));
3.1。使用缓存
缓存允许重用创建昂贵的对象。如果将对象加载到内存中,则可以将其视为对象的缓存。例如,如果从Internet下载图像以在列表中显示它们,则应将它们保存在内存中以避免多次下载它们。
在某些时候,您需要回收一些对象,否则会耗尽内存。这样做的一个好方法是回收在应用程序中使用时间最长的对象。
Android平台提供了 LruCache
类,从API 12开始(或在support-v4库中)。本LruCache
类提供了一个least最近使用的缓存(LRU高速缓存)的缓存实现。LRU缓存会跟踪其成员的使用情况。它具有给定的大小,如果超过此大小,则会删除最长时间未访问的项目。此行为如下图所示。
以下示例代码演示了LruCache
用于缓存图像的类的可能实现。
public class ImageCache extends LruCache<String, Bitmap> {
public ImageCache( int maxSize ) {
super( maxSize );
}
@Override
protected int sizeOf( String key, Bitmap value ) {
return value.getByteCount();
}
@Override
protected void entryRemoved( boolean evicted, String key, Bitmap oldValue, Bitmap newValue ) {
oldValue.recycle();
}
}
它的用法很简单,并通过以下示例代码进行说明。
LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>();
为了确定高速缓存的初始大小,最好根据设备上可用的总内存来确定大小。为了确定可用的内存你可以MemoryClass。以下代码对此进行了演示。
int memClass = ( ( ActivityManager) activity.getSystemService( Context.ACTIVITY_SERVICE ) ).getMemoryClass();
int cacheSize = 1024 * 1024 * memClass / 8;
LruCache cache = new LruCache<String, Bitmap>( cacheSize );
3.2。清理缓存
从API 14开始,您可以覆盖onTrimMemory()
Android组件中的方法。Android系统调用此方法,要求您在Android系统需要前台进程资源的情况下清理内存。
4.链接和文献
需要相关文档链接可以私信我 资料 希望大家多多关注和喜欢~
网友评论