android 优化

1、不要通过Intent 在android基础组件之间传递大数据(binder transaction缓存为1M),可能会导致OOM。
2、新建线程时,必须通过线程池提供(AsyncTask或者TreadPoolExecutor或者其他形式自定义的线程池),不允许在应用中自行显式创建线程。
说明:
使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解 决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。另外创建匿名线程不便于后续的资源使用分析,
对性能分析等会造成困扰。
正解:

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; BlockingQueue taskQueue = new LinkedBlockingQueue();
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue, new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
//执行任务
executorService.execute(new Runnnable() { ...
});

反例:

new Thread(new Runnable() { @Override
public void run() { //操作语句
...
} }).start();
此优化参照阿里巴巴java开发手册。
3、子线程中不能更新界面,更新界面必须在主线程中进行,网络操作不能在 主线程中调用。
4、不要在非 UI 线程中初始化 ViewStub,否则会返回 null。

5、任何时候不要硬编码文件路径,请使用 Android 文件系统 API 访问。
说明:
Android 应用提供内部和外部存储,分别用于存放应用自身数据以及应用产生的用 户数据。可以通过相关 API 接口获取对应的目录,进行文件操作。
正例:
android.os.Environment#getExternalStorageDirectory() android.os.Environment#getExternalStoragePublicDirectory() android.content.Context#getFilesDir() android.content.Context#getCacheDir

public File getDir(String alName) {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), alName); if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created"); }
return file; }

反例:

public File getDir(String alName) {
// 任何时候都不要硬编码文件路径,这不仅存在安全隐患,也让 app 更容易出现适配问题 File file = new File("/mnt/sdcard/Download/Album", alName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created"); }
return file;

6、SharedPreference 提交数据时,尽量使用 Editor#apply(),而非 Editor#commit()。一般来讲,仅当需要确定提交结果,并据此有后续操作时,才使 用 Editor#commit()。
说明:
SharedPreference 相关修改使用 apply 方法进行提交会先写入内存,然后异步写入 磁盘,commit 方法是直接写入磁盘。如果频繁操作的话 apply 的性能会优于 commit,apply 会将最后修改内容写入磁盘。但是如果希望立刻获取存储操作的结果,并据此做相应的其他操作,应当使用 commit。
返例:

editor.putLong("key_name", "long value");
editor.commit();

7、加载大图片或者一次性加载多张图片,应该在异步线程中进行。图片的加 载,涉及到 IO 操作,以及 CPU 密集操作,很可能引起卡顿。
正例:

class BitmapWorkerTask extends AsyncTask {
...
// 在后台进行图片解码
@Override
protected Bitmap doInBackground(Integer... params) {
final Bitmap bitmap = BitmapFactory.decodeFile("some path");
return bitmap; }
...
 }

反例:

Button btnLoadImage = (Button) findViewById(R.id.btn); btnLoadImage.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Bitmap bitmap = BitmapFactory.decodeFile("some path"); }
});

8、在 ListView,ViewPager,RecyclerView,GirdView 等组件中使用图片时, 应做好图片的缓存,避免始终持有图片导致内存泄露,也避免重复创建图片,引起 性 能 问 题 。建 议 使 用 Fresco ( https://github.com/facebook/fresco )、 Glide (https://github.com/bumptech/glide)等图片库。
参考阿里巴巴java开发手册关于Bitmap加载的优化

9、png 图片使用 tinypng 或者类似工具压缩处理,减少包体积。
10、应根据实际展示需要,压缩图片,而不是直接显示原图。手机屏幕比较小, 直接显示原图,并不会增加视觉上的收益,但是却会耗费大量宝贵的内存。

11、针对不同的屏幕密度,提供对应的图片资源,使内存占用和显示效果达到 合理的平衡。如果为了节省包体积,可以在不影响 UI 效果的前提下,省略低密度图 片。

12、将 android:allowbackup 属性设置为 false,防止 adb backup 导出数据。
说明:
在 AndroidManifest.xml 文件中为了方便对程序数据的备份和恢复在 Android API level 8 以后增加了 android:allowBackup 属性值。默认情况下这个属性值为 true,故当 allowBackup 标志值为 true 时,即可通过 adb backup 和 adb restore 来备份和恢复应用程序数据。
正例:


13、在产品的线上版本中关闭调试接口,不要输出敏感信息。因为攻击者可以直接从 Logcat 中读取这些敏感信息。

你可能感兴趣的:(android 优化)