博客
关于我
阅读《阿里巴巴Android开发手册1.0.1》笔记
阅读量:727 次
发布时间:2019-03-21

本文共 4098 字,大约阅读时间需要 13 分钟。

背景

2018年的春节余韵尚未消散,阿里巴巴为移动开发者们准备了一份迟到的新年礼物——《阿里巴巴Android开发手册》1.0.1版本。在此,撰写阅读笔记,记录作为开发者的一些注意事项,规范自身编码习惯。

正文

作为开发者,在日常开发中可能会遇到各种问题,以下是阿里巴巴手册中的一些重要推荐:

1. Activity间通过隐式Intent跳转时,必须经过resolveActivity检查,避免未找到合适组件导致ActivityNotFoundException异常。

避免在发出Intent之前未调用resolveActivity检查,这可能导致系统找不到合适的Activity组件,进而抛出错误。示例代码如下:

public void viewUrl(String url, String mimeType) {    Intent intent = new Intent(Intent.ACTION_VIEW);    intent.setDataAndType(Uri.parse(url), mimeType);    if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {        startActivity(intent);    } else {        // 处理找不到Activity的情况    }}

2. 避免在BroadcastReceiver的onReceive方法中执行耗时操作。若有耗时工作,应使用IntentService完成,而非在BroadcastReceiver内创建子线程。

由于onReceive方法在主线程执行,耗时操作会导致UI不流畅。推荐方法有:使用IntentService、创建HandlerThread或在其他线程中注册BroadcastReceiver。

3. 添加Fragment时,确保FragmentTransaction.commit()在Activity的onPostResume或FragmentActivity的onResumeFragments方法内调用,不要随意使用commitAllowingStateLoss()替代。

FragmentTransaction.commit()如果在Activity保存状态之后调用,可能导致页面恢复时无法还原状态,因而引发 IllegalStateExceptionStateLoss异常。推荐在onPostResume或onResumeFragments中调用commit()。

4. 不要在Activity的onDestroy方法中执行资源释放工作(如销毁线程或停止工作),因为 onDestroy可能执行时间较晚。应在onPause或onStop结合isFinishing判断来执行资源释放。

5. 总是使用显式Intent启动或绑定Service,避免为服务声明IntentFilter。若确实需要使用隐式intent,则可为Service提供intent-filter,并从intent中排除组件名称,并搭配使用setPackage方法。

6. 对于应用内广播,优先使用LocalBroadcastManager注册和发送。LocalBroadcastManager具有更高的安全性和效率。

对于仅用于应用内的广播,建议使用LocalBroadcastManager避免广播泄漏或被拦截,同时提高效率。

7. 在Activity的onPause方法中不要执行耗时操作,因为onPause可能会延迟创建其他Activity,影响页面跳转效率。

8. 文本大小使用单位dp,View大小同样使用单位dp。对于TextView,建议使用wrap_content布局,避免适配问题。

使用dp而非sp,虽然sp长时有早期推荐,但dp更具一致性,避免因系统设置影响UI。

9. 定义全局Toast对象,避免连续显示Toast时无法取消前一次消息的情况。

10. 不允许使用Executors创建线程池,而应通过ThreadPoolExecutor方式明确线程池规则,避免资源耗尽风险。

11. 使用ThreadPoolExecutor设置线程存活时间,确保空闲线程能被释放。

12. 禁止在多进程间使用SharedPreferences共享数据,官方不再推荐。

13. 不要硬编码文件路径,使用Android文件系统API访问。

例如:Environment.getExternalStorageDirectory()、getExternalStoragePublicDirectory()、Context#getFilesDir()、Context#getCacheDir()。

14. 使用外部存储时,必须检查可用性。例如,读写检查isExternalStorageWritable(),只读检查isExternalStorageReadable()。

15. 应用间共享文件时,禁止通过放宽文件系统权限实现,而应使用FileProvider。

避免造成安全风险,如文件权限泄漏。

16. 避免将不受信任外部数据直接拼接SQL语句,如果ContentProvider管理的数据存储在SQL数据库中。

正确做法是使用参数化方式,避免SQL注入。

17. 使用TinyPNG或类似工具压缩PNG图片,减少包体积。

18. 压缩图片而不是直接显示原图,避免内存占用和性能问题。

示例代码如下:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {    BitmapFactory.Options options = new BitmapFactory.Options();    options.inJustDecodeBounds = true;    BitmapFactory.decodeResource(res, resId, options);    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);    options.inJustDecodeBounds = false;    return BitmapFactory.decodeResource(res, resId, options);}

19. 在Activity的onPause或onStop回调中关闭当前正在执行的动画。

示例代码如下:

public class MyActivity extends Activity {    ImageView mImageView;    Animation mAnimation;     @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);            }        });    }     @Override    public void onPause() {        mImageView.clearAnimation();    }}

20. 使用RGB_565代替RGB_888,减少内存占用,视觉效果前后无明显差异。

21. 强依赖onAnimationEnd回调时,为了防止回调异常,可在动画播放完毕后加上超时保护或postDelay替代。

示例代码如下:

View v = findViewById(R.id.xxxViewID);final FadeUpAnimation anim = new FadeUpAnimation(v);anim.setInterpolator(new AccelerateInterpolator());anim.setDuration(1000);anim.setFillAfter(true);new Handler().postDelayed(new Runnable() {    public void run() {        if (v != null) {            v.clearAnimation();        }    }}, anim.getDuration());v.startAnimation(anim);

总结

以上内容为手册中的一些重要推荐,其实内容虽多,但1.0.1版本后还将继续完善。每一点细节都体现出对开发的深思熟虑,希望能为大家的开发工作带来一些启发。

转载地址:http://hjyrz.baihongyu.com/

你可能感兴趣的文章
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>
mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
查看>>
Multiple websites on single instance of IIS
查看>>
mysql CONCAT()函数拼接有NULL
查看>>
multiprocessing.Manager 嵌套共享对象不适用于队列
查看>>
multiprocessing.pool.map 和带有两个参数的函数
查看>>
MYSQL CONCAT函数
查看>>
multiprocessing.Pool:map_async 和 imap 有什么区别?
查看>>
MySQL Connector/Net 句柄泄露
查看>>
multiprocessor(中)
查看>>