六木Sir
六木Sir
## 六、文件与数据库 1. 【强制】任何时候不要硬编码文件路径,请使用 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 =...
## 七、Bitmap、Drawable 与动画 1. 【强制】加载大图片或者一次性加载多张图片,应该在异步线程中进行。图片的加 载,涉及到 IO 操作,以及 CPU 密集操作,很可能引起卡顿。 正例: ``` class BitmapWorkerTask extends AsyncTask { -- ... // 在后台进行图片解码 @Override protected Bitmap doInBackground(Integer... params) { final Bitmap bitmap...
## 八、安全 1. 【强制】使用 PendingIntent 时,禁止使用空 intent,同时禁止使用隐式 Intent 说明: 1)使用 PendingIntent 时,使用了空 Intent,会导致恶意用户劫持修改 Intent 的内 容。禁止使用一个空 Intent 去构造 PendingIntent,构造 PendingIntent 的 Intent 一定要设置 ComponentName 或者 action。 2)PendingIntent 可以让其他 APP 中的代码像是运行自己...
## 九、其他 1. 【强制】不要通过 Msg 传递大的对象,会导致内存问题。 2. 【强制】不能使用 System.out.println 打印 log。 正例: ``` Log.d(TAG, "Some Android Debug info ..."); ``` 反例: ``` System.out.println("System out println ..."); ``` 3. 【强制】Log 的...
## 周计划Android进阶之旅(2018.7.23-2018.8.5) ### UI源码级分析 ### 输出 输出至少一片文档总结
# Android包管理框架:APK的安装流程 **文章目录** 我们来思考一下Android系统是如何安装一个APK文件的,从直观的流程上,当我们点击一个APK文件或者从应用商店下载一个APK文件,会弹起一个安装对话框,点击安装就可以安装应用。 那么这里面的流程是什么样的呢?🤔 首先很容易想到的是,Android根据文件类型MimeType来判断是否弹起安装页面,就行点击一个视频会调起视频播放器一样。 Android系统常见的文件类型如下所示: 👉 [MimeUtils.java](https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/libcore/net/MimeUtils.java) - add("application/zip", "zip"); - add("application/vnd.android.package-archive", "apk"); - add("video/mp4", "mp4"); - add("video/3gpp", "3gpp"); - add("text/plain", "txt"); - add("image/gif", "gif"); - add("image/ico", "ico");...
# Android包管理框架:APK的加载流程 **文章目录** 我们前面说过APK可以分为代码与资源两部分,那么在加载APK时也会涉及代码的加载和资源的加载,代码的加载事实上对应的就是Android应用进程的创建流程,关于这一块的内容我们在文章[01Android进程框架:进程的创建、启动与调度流程](https://github.com/qmsggg/android-open-source-project-analysis/blob/master/doc/Android系统底层框架篇/Android进程框架/01Android进程框架:进程的创建、启动与调度流程.md)已经分析过,本篇文章 我们着重来分析资源的加载流程。 我们知道在代码中我们通常会通过getResource()去获取Resources对象,Resource对象是应用进程内的一个全局对象,它用来访问应用的资源。除了Resources对象我们还可以通过getAsset()获取 AssetManger来读取指定文件路径下的文件。Resource与AssetManger这对兄弟就构造了资源访问框架的基础。 那么AssetManager对象与Resources对象在哪里创建的呢?🤔 ### 3.1 AssetManager的创建流程 我们知道每个启动的应用都需要先创建一个应用上下文Context,Context的实际实现类是ContextImpl,ContextImpl在创建的时候创建了Resources对象和AssetManager对象。 AssetManager对象创建序列图如下所示: 我们可以发现在整个流程AssetManager在Java和C++层都有一个实现,那么它们俩有什么关系呢?🤔 >事实上实际的功能都是由C++层的AssetManag来完成的。每个Java层的AssetManager对象都一个long型的成员变量mObject,用来保存C++层 AssetManager对象的地址,通过这个变量将Java层的AssetManager对象与C++层的AssetManager对象关联起来。 ```java public final class AssetManager implements AutoCloseable { // 通过这个变量将Java层的AssetManager对象与C++层的AssetManager对象关联起来。 private long mObject; }...
# Android进程框架:线程与线程池 **文章目录** - 一 线程原理 - 1.1 线程创建 - 1.2 线程调度 - 二 线程同步 - 2.1 volatile - 2.2 synchronized - 三 线程池 - 3.1 线程池调度 - 3.2 线程池配置...
# Android进程框架:线程通信的桥梁Handler **文章目录** - 一 消息队列的创建 - 1.1 建立消息队列 - 1.2 开启消息循环 - 二 消息的添加 - 三 消息的分发和处理 - 3.1 消息分发 - 3.2 消息处理 第一次阅览本系列文章,请参见[导读](https://github.com/qmsggg/android-open-source-project-analysis/blob/master/doc/导读.md),更多文章请参见[文章目录](https://github.com/qmsggg/android-open-source-project-analysis/blob/master/README.md)。 Android是一个消息驱动型的系统,消息机制在Android系统中扮演者重要的角色,与之相关的Handler也是我日常中常用的工具。今天我们就来聊一聊这个。 Android消息循环流程图如下所示: 主要涉及的角色如下所示: - Message:消息,分为硬件产生的消息(例如:按钮、触摸)和软件产生的消息。...
# Android进程框架:进程通信的桥梁Binder **文章目录** 千呼万唤始出来,Android系统源码分析终于来到了Binder IPC通知机制这一块,我们知道Android应用的基础是四大组件,而四大组件通信的基础就是就是Binder,可以说它是Android系统 最重要的组成部分,对于开发者而言也是最难理解的一部分。 但古人云"天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣",本文将尝试以通俗易懂的方式来讲解这一块的原理。 在分析Binder原理之前,我们先来思考一个问题,Linux系统本身有许多IPC手段,为什么Android要重新设计一套Binder机制呢?🤔 为什么选用Binder,在讨论这个问题之前,我们知道Android也是基于Linux内核,Linux现有的进程通信手段有以下几种: 1. 管道:在创建时分配一个page大小的内存,缓存区大小比较有限; 2. 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信; 3. 共享内存:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决; 4. 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信; 5. 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。6. 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等; 既然有现有的IPC方式,为什么重新设计一套Binder机制呢。主要是出于以上三个方面的考量: - 高性能:从数据拷贝次数来看Binder只需要进行一次内存拷贝,而管道、消息队列、Socket都需要两次,共享内存不需要拷贝,Binder的性能仅次于共享内存。 - 稳定性:上面说到共享内存的性能优于Binder,那为什么不适用共享内存呢,因为共享内存需要处理并发同步问题,控制负责,容易出现死锁和资源竞争,稳定性较差。而Binder基于C/S架构,客户端与服务端彼此独立,稳定性较好。 - 安全性:我们知道Android为每个应用分配了UID,用来作为鉴别进程的重要标志,Android内部也依赖这个UID进行权限管理,包括6.0以前的固定权限和6.0以后的动态权限,传荣IPC只能由用户在数据包里填入UID/PID,这个标记完全 是在用户空间控制的,没有放在内核空间,因此有被恶意篡改的可能,因此Binder的安全性更高。 我们再来看看Binder通信机制的整体框架,如下图所示:...