一篇文章搞定Android性能优化

版权声明:本文为博主原创文章,转载请注明出处!谢谢! https://blog.csdn.net/aaa1050070637/article/details/85115515

 


目录

1. 基本组件 2

2. UI布局 2

3. 进程、线程、消息通讯 3

4. 文件和数据库 3

5. Bitmap、动画、drawable 4

6. 安全和信息安全规范 4

 

基本组件

  1. Activity之间数据通信,当数据量较大时,避免采用Intent+Parcelable的方式,可以考虑EventBus等替代方案,避免造成TransactionTooLargeException;
  2. Activity隐式,在发出Intent跳转之前,需要对Activity进行ResolveActivity检查,以免造成ClassNotFoundException; 代码示例:if(getPackageManager.resolveActivity(intent,PackageManager.MATCH_DEFAULT_ONLY)!=NULL)
  3. 避免在Service#onstartCommand()以及OnBind()方法中执行耗时操作,如的确有需求,可以用IntentService或者其他异步机制来完成;
  4. 避免在BroadCastReceiver的onReceive()方法中执行耗时操作,有需求同上,可以采用IntentService完成,不能在方法体内直接new Thread()来完成;
  5. 对于只运用于应用内的BroadCastReceiver,尽量使用LocalBroadCastManager进行注册和发送,原因是安全性更好,并且具有更高的运行效率;
  6. 当前Activity中的onPause方法会执行完毕后,才会执行下一个Activity的onCreate()方法,所以避免在onPasue方法中执行时间较长的操作,影响跳转效率;
  7. 不要再Android中的Application中缓存数据,组件间的数据通讯,尽量使用Intent机制,也可以使用sharePreference来使数据持久化;
  8. Activity与Fragment中动态注册广播时,一定要注意register与unRegister要成对出现;

UI布局

  1. 布局中不得不使用ViewGroup多层嵌套时,尽量不要用LinearLayout,使用RelativeLayout可以有效降低嵌套层级;
  2. 在Activity中使用对话框、弹出浮层时,尽量用DialogFragment,而不是Dialog/AlertDialog,这样可以使Activity方便对对话框/弹出浮层进行生命周期管理;
  3. 禁止在非UI现场进行View操作;
  4. 禁止在设计布局时,多次对子Viewh和父View进行同样背景的设置,避免多次绘制,建议及时隐藏不需要显示的布局;
  5. 灵活使用布局,建议用Merge标签、ViewStub来优化布局,尽可能少的减少嵌套层级,推荐使用FrameLayout、LinearLayout、RelativeLayout次之;

进程、线程、消息通讯

  1. 不要通过Intent在Android基础组件中传递大数据(binder transaction中的缓存为1M),避免出现OOM;
  2. 在Application中初始化数据时,加入进程判断,确保在自己需要的进程进行初始化,特别是在后台进程中尽量避免不必要的初始化;
  3. 如非必要,尽量少创建线程,建议用线程池对线程进行管理;
  4. 创建线程池使用ThreadPoolExecutor创建,而不是Executor,这样可以使开发者更加明白线程池的运行规则,避免资源消耗;
  5. 新建线程时,定义自己能识别的业务线程名称,便于性能优化和功能排查;
  6. ThreadPoolExecutor创建时设置存活时间(setKeppAliveTime),确保空闲时,线程及时被释放;
  7. 不要用SharedPreferences用于进程数据共享;
  8. 进程间数据共享中,使用数据库,而不是sp,文件,以及Intent直接传递;

文件和数据库

  1. 任何时候不要使用硬编码文件路径,使用Android文件系统API进行访问;(Environment)
  2. 使用外部存储时,必须先检查外部存储的可用性;
  3. 应用间共享文件时,不能使用放宽文件系统访问权限的方式,而使用FileProvider;
  4. SharedPreferences提交数据时,尽量使用Editor#apply()方法,而不是Editor#commit()方法。一般来讲,只有当确定提交结果,并根据结果有后续操作时,才能用Editor#commit()方法;
  5. 数据库Cursor使用完毕后,一定要记得关闭,以免造成内存泄漏;
  6. 多线程操作使用数据库时,需要使用事务,以免出现同步的问题;db.beginTransaction;db.setTransactionSuccessful,使用完毕db.endTransaction;
  7. 数据库进行大数据操作时,尽量使用事务或者其他方式,来保证执行的效率;
  8. 执行数据库语句时,使用SQLiteDataBase#insert()、delete()、update()等方法,不要使用SQLiteDatabase#exeSQL(),以免SQlite注入风险;
  9. 如果ContentProvider中存储的数据在SQL中,应该避免直接将外来不受信任的数据直接拼接在原始数据库语句中,使用一个将“?”作为可替换参数的选择句子,或者使用一个单独的选择参数数组,能有效避免SQL注入风险。

例:String mSelectionCause=”var=?”;

    String selectionArgs[] ={“”};

 

Bitmap、动画、drawable

  1. 加载大图片或者多图片时,应该使用异步操作,因为图片的加载涉及IO操作,以及CPU密集操作,很可能引起卡顿;
  2. 在ListView、ViewPager、RecyclerView、GridView中使用图片时,及时做好图片的缓存,避免始终持有图片,导致内存泄漏。也避免重复创建图片, 导致性能降低。建议使用Fresco、Glide框架来加载图片;
  3. Png图片使用tinyPng或者类似的工具进行压缩处理,减少包体积;
  4. 图片使用完毕之后,及时回收资源,释放内存;
  5. 使用ARGB-565替换ARGB-888,在视觉要求不高的情况下,能有效减少内存占用;
  6. 在Activity中的onPause方法和onStop方法中,停止当前页面动画的播放;

安全和信息安全规范

  1. 使用PendingIntent时,禁止使用空的Intent以及隐式意图;
  2. 禁止使用常量初始化矢量参数构建IvParameterSpec,建议IV通过随机方式产生;
  3. 将android:allowbackup属性设置为false,防止adb backup导出数据;
  4. 在实现的HostnameVerifier子类中,需要使用verify函数校验服务器主机名的合法性,否则会导致恶意程序利用中间人攻击绕过主机名校验;
  5. 利用X509TrustManager子类中的checkServerTrsuted函数校验服务端证书的合法性;
  6. META-INF目录中不能包含apk,odex,so等敏感文件,该文件没有经过签名,容易被恶意替换;
  7. Receiver/Provider不能再汉武权限控制的情况下,将android:export设置为true;
  8. 阻止WebView通过filsescheme方式访问本地敏感数据;
  9. 不要广播敏感信息,只能在本应用中使用LocalBroadcast,避免被别的应用手动,或者setPackage做限制;
  10. 不要把敏感信息打印到Log日志中;
  11. 对于内部使用的组件,显示设置组件的android:exported属性为false;
  12. 应用发布前确保android:debuggable属性设置为false;
  13. 使用IntentScheme URL需要做过滤;
  14. 除非min API level>=17,请注意addJvascriptInterface的使用;
  15. 传输使用Https协议证书至少强校验;
  16. 敏感数据要进行加密传输;
  17. 前端数据不可信,后端数据要校验;
  18. 敏感系统使用VPN进行连接;
  19. 本地不能明文保存个人敏感数据,敏感数据要加密保存;
  20. 本地不能保存账号和密码;
  21. 不要使用MSG传递大的对象,会导致内存问题;
  22. 不要使用system.out.print打印log日志;
  23. Log日志中的tag不能为空;

 

猜你喜欢

转载自blog.csdn.net/aaa1050070637/article/details/85115515