您的位置:首页 > 移动开发 > Android开发

android 性能优化浅谈

2017-06-09 15:14 190 查看

本文介绍了一些有效的性能优化方法,主要内容包括布局 优化、绘制优化、内存泄漏优化、响应速度 优化、ListView优化、Bitmap优化、线程优化以及一些性能优化的建议。感谢《android开发艺术探索》的指导。


一、布局优化

1,ViewStub  当使用的才会加载

2,include    重用布局

3,merge     减少布局的层级

二、绘制优化

指在View的onDraw中要避免执行大量操作。

三、内存泄漏优化

常出现的场景:

①静态常量无法释放导致的内存泄漏

②单例模式拥有某个类的对象,导致的无法释放,内存泄漏

③属性动画没有销毁,界面已经销毁。但是动画还是在运行。(在onDestroy中销毁动画)

四、响应速度优化

避免在主线程中做耗时工作。activity  5秒无法相应屏幕触摸事件或者键盘输入事件、BroadcastReceiver如果10秒还未完成操作。

五、ListView和Bitmap优化

ListView:

①采用Viewholder并避免在getView中执行耗时工作。

②要根据列表的滑动状态来控制任务的执行频率。(比如快速滑动时不适合开启大量异步任务,可以在用户滑动的时候停止异步加载。)

public void onScrollStateChanged(AbListView view, intscrollState){

   if(scrollState==OnScrollListener.SCROLL_STATE_IDLE){

       mIsGridViewIdle=true;

       mImageAdapter.notifyDataSetChanged();

   }else{

       mIsGridViewIdle=false;

   }

}

if(mIsGridViewIdle&&mCanGetBitmapFromNetWork){

   imageView.setTag(uri);

   mIMageLoader.bindBitmap(uri,imageView,mImageWidth,mImageWidth);

}

③开启硬件加速使滑动就流畅(通过设置android:hardwareAccelerated="true"可为)。

Bitmap:

BitmapFactory加载的四类方法:

①decodeFile②decodeResource③decodeStream④decodeByteArray

decoderfile和decodeResource间接调用了decodeStream

如何高效记载bitmap:

1)将BitmapFactory.Options的inJustDevodeBounds设为true并加载图片。

2)从BitmapFactory.Options中取出图片的原始宽高信息,他们对应与outWidth和outHeight参数。

3)根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize。

4)将BitmapFactoryOptions的inJustDecodeBounds参数设为false,然后加载图片。

实现:

public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId,int reqWidth,intreqHeight){

   //Firstdecode with inJustDecodeBounds=tru to check dimensions

   final BitmapFactory.Options options=new BitmapFactory.Options();

   options.inJustDecodeBounds=true;

   BitmapFactory,decideResource(res,resId,options);

   //colculate inSampleSize

   options.inSampleSize=calculateInSampleSize(options,reqWidth,reqHeight);

   

   //Decode bitmap with inSampleSize set

   options.inJustDecodeBounds=false;

   return BitmapFactory.decodeResource(res,resId,options);

}

//calculateInSampleSize

public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){

    //Raw height and width of image

    final int height=options.outHeight;

    final int height=options.outWidht;

    int inSampleSize=1;

    if(height>reqHeight||widht>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;

}

使用:

如果期望得到大小为100x100像素的图片。

mImageView.setImageBitmap(decodeSampleBitmapResource(getResources(),R.id.myimage,100,100));

6线程优化

使用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程。从而避免线程创建和销毁所带来的开销。

同时还能有效的控制线程池的并发数。避免大量线程因互抢资源导致阻塞。还能 对线程进行简单管理,并提供定时执行以及指定间隔循环执行。

线程池分类:

1,FixedThreadPool

2,CachedThreadPool

3,ScheduledThreadPool

4,SingleThreadExecutor

这里就不详细说明这四种类型的功能特性,请大家自行搜索。但他们的都是通过ThreadPoolExecutor实现的。

public ThreadPoolExecutor(

int corePoolSize,    

int maximumPoolSize,  

long keepAliveTime,

TimeUnit unit,

BlockingQueue<Runnable> workQueue,

ThreadFactory threadFactory)

解析:

corePoolSize:核心线程数,默认情况下,核心线程会在线程池一直存活,及时他们 处于闲置状态。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的核心线程在等待新任务到来时会有超时策略,这个时间间隔由keepAliveTime决定。

maximumPoolSize:所能容纳最大线程数,活动线程达到这个值后,后续新任务会呗阻塞。

keepAliveTime:非核心线程闲置时的超时时长,超过就被回收。当allowCoreThreadTimeOut为true的时候,同样会作用于核心线程。

unit:指定keepAliveTime参数的时间单位,值有TimeUnit.MILLISECONDS(毫秒),TimeUnit.SECONDS(秒),TimeUnit.MINUTES(秒)等。

workQueue:线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中。

threadFactory:线程工厂,为线程池提供创建新线程的功能。ThreadFactory是一个接口.

它只有一个方法:Thread newThread(Runnable r);

最后给大家的优化建议

1)避免创建过多的对象。

2)不要过多使用枚举,枚举占用的内存空间要比整形大。

3)常量请使用static final 来修饰。

4)使用安卓特有的数据结构,比如SparseArray和Pair等,他们都具有更好的性能。

5)适当使用软引用,和弱引用。

6)采用内存缓存和磁盘缓存。

7)尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏。

(内存泄漏工具分析------MAT)

8)尽量用局部变量

10)合理使用浮点类型

11)及时动态回收不用的资源(str=null,btm.Recycle())

12)移除Acitivty默认背景,getWindow().setBackgroundDtawable(null)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化