Android内存和性能优化 - 教程

作者: python草莓 | 来源:发表于2019-05-20 17:25 被阅读12次

    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缓存会跟踪其成员的使用情况。它具有给定的大小,如果超过此大小,则会删除最长时间未访问的项目。此行为如下图所示。

    image.png

    以下示例代码演示了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.链接和文献

    需要相关文档链接可以私信我 资料 希望大家多多关注和喜欢~

    相关文章

      网友评论

        本文标题:Android内存和性能优化 - 教程

        本文链接:https://www.haomeiwen.com/subject/wqokzqtx.html