版权声明:本文出自汪磊的博客,转载请务必注明出处。

本篇继续上一篇《阿里巴巴Android编码规范》阅读纪要(一) ,还是建议各位同学有时间完整阅读一下《阿里巴巴Android编码规范》,如果实在没时间,就看我的本系列博客吧,主要摘录一些个人认为比较重要的地方。

UI 与布局部分

1,不能使用 ScrollView 包裹 ListView/GridView/ExpandableListVIew;因为这样会把 ListView 的所有 Item 都加载到内存中,要消耗巨大的内存和 cpu 去绘制图面。

说明:

ScrollView 中嵌套 List 或 RecyclerView 的做法官方明确禁止。除了开发过程中遇到的各种视觉和交互问题,这种做法对性能也有较大损耗。ListView 等 UI 组件自身有垂直滚动功能,也没有必要在嵌套一层 ScrollView。目前为了较好的 UI 体验,更贴近 Material Design 的设计,推荐使用 NestedScrollView。

正例:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout>

  <android.support.v4.widget.NestedScrollView>

    <LinearLayout>

      <ImageView/>

...

      <android.support.v7.widget.RecyclerView/>

    </LinearLayout>

  </android.support.v4.widget.NestedScrollView>

</LinearLayout>

反例:

<ScrollView>

  <LinearLayout>

    <TextView/>

    ...

    <ListView/>

    <TextView />
  </LinearLayout> </ScrollView>

进程、线程与消息通信部分

1,新建线程时,必须通过线程池提供(AsyncTask 或者 ThreadPoolExecutor或者其他形式自定义的线程池),不允许在应用中自行显式创建线程。

说明

使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。另外创建匿名线程不便于后续的资源使用分析,对性能分析等会造成困扰。

2,线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:

Executors 返回的线程池对象的弊端如下:

1) FixedThreadPool 和 SingleThreadPool : 允 许 的 请 求 队 列 长 度 为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM;

2) CachedThreadPool 和 ScheduledThreadPool :允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

关于线程池学习可以参考我之前写的两篇博客java线程池技术(一):ThreadFactory与BlockingQueuejava线程池技术(二): 核心ThreadPoolExecutor介绍。

3,不要在非 UI 线程中初始化 ViewStub,否则会返回 null。

4,禁止在多进程之间用SharedPreferences共享数据,虽然可以(MODE_MULTI_PROCESS),但官方已不推荐。

文件与数据库部分

1,SharedPreference提交数据时,尽量使用Editor#apply() ,而非Editor#commit()。一般来讲,仅当需要确定提交结果,并据此有后续操作时,才使用 Editor#commit()。

说明:

SharedPreference 相关修改使用 apply 方法进行提交会先写入内存,然后异步写入磁盘,commit 方法是直接写入磁盘。如果频繁操作的话 apply 的性能会优于 commit,apply 会将最后修改内容写入磁盘。但是如果希望立刻获取存储操作的结果,并据此做相应的其他操作,应当使用 commit。

正例:

public void updateSettingsAsync() {

  SharedPreferences mySharedPreferences = getSharedPreferences("settings", Activity.MODE_PRIVATE);
  SharedPreferences.Editor editor = mySharedPreferences.edit();
  editor.putString("id", "foo");
  editor.apply();
} public void updateSettings() {   SharedPreferences mySharedPreferences = getSharedPreferences("settings", Activity.MODE_PRIVATE);
  SharedPreferences.Editor editor = mySharedPreferences.edit();
  editor.putString("id", "foo");
  if (!editor.commit()) {
  Log.e(LOG_TAG, "Failed to commit setting changes");
}

反例:

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

2,大数据写入数据库时,请使用事务或其他能够提高 I/O 效率的机制,保证执行速度。

正例:

public void insertBulk(SQLiteDatabase db, ArrayList<UserInfo> users) { 

  db.beginTransaction();
  try {     for (int i = 0; i < users.size; i++) {     ContentValues cv = new ContentValues();     cv.put("userId", users[i].userId);     cv.put("content", users[i].content);     db.insert(TUserPhoto, null, cv);
  }
  // 其他操作
  db.setTransactionSuccessful();   } catch (Exception e) {     // TODO
  } finally {     db.endTransaction();
  }
}

3,执行 SQL 语句时,应使用 SQLiteDatabase#insert()、update()、delete(),不要使用 SQLiteDatabase#execSQL(),以免 SQL 注入风险。

Bitmap、Drawable 与动画

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

2,png 图片使用 tinypng 或者类似工具压缩处理,减少包体积。

个人简要说明:TinyPng官网地址:https://tinypng.com/。TinyPng能够对PNG和JPG/JPEG格式图片进行有效压缩,图片体积大幅减小,可达六七成,并且失真较小。

3,使用完毕的图片,应该及时回收,释放宝贵的内存。

正例:

Bitmap bitmap = null;

loadBitmapAsync(new OnResult(result){

  bitmap = result;

});

...使用该 bitmap...

//使用结束,在 2.3.3 及以下需要调用 recycle()函数,在 2.3.3 以上 GC 会自动管理,除非你明确不需要再用。
if (Build.VERSION.SDK_INT <= 10) {   bitmap.recycle();
}
bitmap = null;

4,在 Activity.onPause()或 Activity.onStop()回调中,关闭当前 activity 正在执行的的动画。

正例:

public class MyActivity extends Activity {

ImageView mImageView;

Animation mAnimation;

Button mBtn;
/** 首次创建 activity 时调用 */
@Override
public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);
  setContentView(R.layout.main);   mImageView = (ImageView)findViewById(R.id.ImageView01);
  mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim);
  mBtn= (Button)findViewById(R.id.Button01);
  mBtn.setOnClickListener(new View.OnClickListener() {     @Override
    public void onClick(View v) {       mImageView.startAnimation(mAnimation);
    }
  });
} public void onPause() {     //页面退出,及时清理动画资源
    mImageView.clearAnimation()   }
}

5,使用 ARGB_565 代替 ARGB_888,在不怎么降低视觉效果的前提下,减少内存占用。

说明:

android.graphics.Bitmap.Config 类中关于图片颜色的存储方式定义:

1)ALPHA_8 代表 8 位 Alpha 位图;

2)ARGB_4444 代表 16 位 ARGB 位图;

3)ARGB_8888 代表 32 位 ARGB 位图;

4)RGB_565 代表 8 位 RGB 位图。

位图位数越高,存储的颜色信息越多,图像也就越逼真。大多数场景使用的是 ARGB_8888 和 RGB_565,RGB_565 能够在保证图片质量的情况下大大减少内存的开销,是解决oom的一种方法。

但是一定要注意 RGB_565 是没有透明度的,如果图片本身需要保留透明度,那么就不能使用 RGB_565。

正例:

Config config = drawableSave.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888 :
Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(w, h, config);

反例:

Bitmap newb = Bitmap.createBitmap(width, height, Config.ARGB_8888);

安全部分

1,将 android:allowbackup 属性设置为 false,防止 adb backup 导出数据。

说明:

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

正例:

<application

  android:allowBackup="false"

  android:largeHeap="true"

  android:icon="@drawable/test_launcher"

  android:label="@string/app_name"

  android:theme="@style/AppTheme" >

2,数据存储在 Sqlite 或者轻量级存储需要对数据进行加密,取出来的时候进行解密。

3,使用 Android 的 AES/DES/DESede 加密算法时,不要使用默认的加密模式ECB,应显示指定使用 CBC 或 CFB 加密模式。

说明:

加密模式 ECB、CBC、CFB、OFB 等,其中 ECB 的安全性较弱,会使相同的铭文在不同的时候产生相同的密文,容易遇到字典攻击,建议使用 CBC 或 CFB 模式。

1) ECB:Electronic codebook,电子密码本模式

2) CBC:Cipher-block chaining,密码分组链接模式

3) CFB:Cipher feedback,密文反馈模式

4) OFB:Output feedback,输出反馈模式

4,对于不需要使用 File 协议的应用,禁用 File 协议,显式设置 webView.getSettings().setAllowFileAccess(false),对于需要使用 File 协议的应用,禁止 File 协议调用 JavaScript,显式设置 webView.getSettings().setJavaScriptEnabled(false)。

5,Android5.0 以后安全性要求较高的应用应该使用 window.setFlag (LayoutParam.FLAG_SECURE) 禁止录屏。

6,Android WebView 组件加载网页发生证书认证错误时,采用默认的处理方法handler.cancel(),停止加载问题页面。

说明:

Android WebView 组件加载网页发生证书认证错误时,会调用 WebViewClient 类的 onReceivedSslError 方法,如果该方法实现调用了 handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露.

反例:

mWebView.getSettings().setJavaScriptEnabled(true); 
mWebView.addJavascriptInterface(new JsBridge(mContext), JS_OBJECT);
mWebView.loadUrl("http://www.example.org/tests/addjsif/");
mWebView.setWebViewClient(new WebViewClient() {   @Override
  public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {     handler.proceed(); // 忽略 SSL 证书错误
  } });

好了,以上就是阅读《阿里巴巴Android编码规范》中个人摘录的一些觉得需要注意的地方,如果感兴趣可以自行查找完整版全部阅读一下。

本篇到此结束,希望对你有用。

《阿里巴巴Android编码规范》阅读纪要(二)的更多相关文章

  1. 《阿里巴巴Android编码规范》阅读纪要(一)

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 2月28日阿里巴巴首次公开内部安卓编码规范,试想那么多业务线,开发人员,没有一套规范管理起来是多么麻烦,以下是个人阅读Android基本组件部分过程 ...

  2. 浅谈Android编码规范及命名规范

    前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...

  3. 最全面的 Android 编码规范指南

    最全面的 Android 编码规范指南 本文word文档下载地址:http://pan.baidu.com/s/1bXT75O 1. 前言 这份文档参考了 Google Java 编程风格规范和 Go ...

  4. 【转】Android编码规范建议18条

    转自:http://www.chinaz.com/design/2015/0908/443732.shtml Android编码规范建议18条 适合手机app设计师和android 工程师阅读. 1. ...

  5. 最详细最权威的Android 编码规范

    1. 前言 这份文档参考了 Google Java 编程风格规范和 Google 官方 Android 编码风格规范.该文档仅供参考,只要形成一个统一的风格,见量知其意就可. 1.1 术语说明 在本文 ...

  6. 阿里巴巴Java编码规范插件安装使用指南

    编码规范插件安装使用指南 阿里技术公众号公布的<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,后又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来. 为了让开发 ...

  7. Android编码规范01

    目标: 掌握Java & Android命名规范 在研究Android源代码的基础上改进命名规范 考核内容 说出四种常用的命名法 比较java和C#的命名规范的不同点 总结: 读不同程序员写的 ...

  8. 编码规范系列(二):Eclipse Checkstyle配置

    http://chenzhou123520.iteye.com/blog/1627618 上一篇介绍了<编码规范系列(一):Eclipse Code Templates设置>,这篇主要介绍 ...

  9. 【Android学习】Android编码规范

    四种常见的命名法 比较Java和c#的命名规范的不同点 常量用大写 java方法首字母不大写,应该小写 函数行数限制 不要用拼音 参照物,Android源码 看源码工具,SourceInsight 和 ...

随机推荐

  1. crack the coding interview

    crack the coding interview answer c++ 1.1 #ifndef __Question_1_1_h__  #define __Question_1_1_h__  #i ...

  2. spring 完成multipart数据上传

    spring中多媒体文件的上传,通过配置 MultipartResolver 实现. MultipartResolver 的实现类有两个:一.StandardServletMultipartResol ...

  3. Yaf框架的配置

    http://www.laruence.com/manual/yaf.ini.html //先看一下惠新宸鸟哥yaf官网的配置说明 我们可以在php.ini中定义开发环节配置项,把本地开发设置成dev ...

  4. Centos下的GitLab的安装汉化和数据备份以及管理员密码重置

    前言: 安装版本:gitlab-ce-8.8.5-ce.1.el7.x86_64.rpm 下载地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yu ...

  5. 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache

    接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...

  6. Spring注解简介

    提供了基于注解(Annotation-based)的配置,我们可以通过注解的方式来完成注入依赖. 1. 使用注解方式配置 我们需要修改spring配置文件的头信息,修改部分红色标注,如下: <c ...

  7. linux web服务器及LAMP动态网站平台搭建

    (vim补:)vim另存为:x,x w 目标文件路径vim批量删除x:x,x d Web服务:基于B/S架构的web通信服务端:支持HTTP协议的网页提供程序客户端:按标记规范显示网页的浏览器程序客户 ...

  8. DataCleaner第一章

    Part1. Introduction to DataCleaner 介绍DataCleaner |--What is data quality(DQ) 数据质量? |--What is data p ...

  9. 利用 xrandr 命令修改屏幕分辨率

    问题背景 电脑外接着一个 23' 的显示器,分辨率为 1920*1080. 操作系统:ubuntu 14.04 今天,通过 Setting->Displays 中选择外接屏的分辨率时,发现最大只 ...

  10. Hidden Markov Models(HMM) 初理解

    1. 一个简单例子