标签:【每日一题】
25. 描述下 Android 数字签名 【2018.1.26】
在 Android 系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系。
Android 系统要求每一个安装进系统的应用程序都是经过数字证书签名的,数字证书的私钥则保存在程序开发者的手中。Android将数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序。
这个数字证书并不需要权威的数字证书签名机构认证(CA),它只是用来让应用程序包自我认证的。
同一个开发者的多个程序尽可能使用同一个数字证书,这可以带来以下好处。
(1)有利于程序升级,当新版程序和旧版程序的数字证书相同时,Android 系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。
(2)有利于程序的模块化设计和开发。Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。
在签名时,需要考虑数字证书的有效期:
(1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改数字证书的程序将不能正常升级。
(2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序的预计生命周期。
(3)Android Market 强制要求所有应用程序数字证书的有效期要持续到 2033 年 10 月 22 日以后。
Android 数字证书包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android 系统不会安装一个没有数字证书的应用程序
(2)Android 程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个 Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用 adt 插件或者 ant 工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android 只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装
在系统中,即使证书过期也不会影响程序的正常功能
24. Android 中布局的优化措施都有哪些?
1、尽可能减少布局的嵌套层级
可以使用 sdk 提供的hierarchyviewer工具分析视图树,帮助我们发现没有用到的布局。
2、不用设置不必要的背景,避免过度绘制
比如父控件设置了背景色,子控件完全将父控件给覆盖的情况下,那么父控件就没有必要设置背景。
3、使用include
标签复用相同的布局代码
4、使用merge
标签减少视图层次结构
该标签主要有两种用法:
1) 因 为 所 有 的 Activity 视 图 的 根 节 点 都 是 FrameLayout , 因 此 如 果 我 们 的 自 定 义 的 布 局 也 是FragmenLayout 的时候那么可以使用 merge 替换。
2) 当应用 Include或者ViewStub标签从外部导入xml结构时,可以将被导入的 xml 用 merge作为根节点表示,这样当被嵌入父级结构中后可以很好的将它所包含的子集融合到父级结构中,而不会出现冗余的节点。
merge
只能作为 xml 布局的根元素。
5、通过ViewStub
实现 View 的延迟加载
23. android:layout_gravity 和 android:gravity 的区别?
第一个是让该布局在其父控件中的布局方式,第二个是该布局布置其子视图的布局方式。
22. Padding 和 Margin 有什么区别?
padding内填充,margin外边距
padding 是站在父 view的角度描述问题,它规定它里面的内容必须与这个父 view 边界的距离。margin则是站在自己的角度描述问题,规定自己和其他(上下左右)的view之间的距离,如果同一级只有一个view,那么它的效果基本上就和 padding 一样了。
21. 什么是 ANR 如何避免它?
在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR 给用户。
不同的组件发生 ANR 的时间不一样,主线程(Activity、Service)是 5 秒,BroadCastReceiver 是 10 秒。
解决方案:
将所有耗时操作,比如访问网络,Socket 通信,查询大量 SQL 语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage、runonUITread、AsyncTask等方式更新UI。无论如何都要确保用户界面操作的流畅度。如果耗时操作需要让用户等待,那么可以在界面上显示进度条。
20. Android中的动画 【2018.1.25更新】
主要有三种动画:帧动画、补间动画、属性动画(3.0增加)。
补间动画,通过在两个关键帧之间补充渐变的动画效果来实现,其优点是可以节省空间
帧动画,其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。图片不易过多过大,不然容易产生OOM。
属性动画,改变的是对象的实际属性,ValueAnimator和ObjectAnimator是属性动画的两个核心类。
19. Android中的常用布局
- Linearlayout 线性布局
- RelativeLayout 相对布局
- FrameLayout 帧布局
- GridLayout 网格布局
- TableLayout 表格布局
- AbsoluteLayout 绝对布局
- ConstraintLayout 约束布局
18. Android中的四大组件
- Activity
- Service
- BroadcastReceiver
- ContentProvider
只有广播可以不在清单文件中注册
17. Android 中数据存储方式有哪些?
- 文件存储
- xml,SharedPreference
- SQLiteDatabase
- ContentProvider
- 网络
16. sp 频繁操作有什么后果?sp 能存多少数据?【2018.1.24】
Sp 的底层是由 xml 来实现的,操作 sp 的过程就是 xml的序列化和解析的过程。Xml 是存储在磁盘上的,因此考虑到需要 I/O 速度问题,sp 不适宜频繁操作。同时序列化 xml是就是将内存中的数据写到 xml 文件中,由于 dvm 的内存是很有限的,因此单个 sp文件不建议太大,具体多大是没有一个具体的要求的,但是我们知道 DVM 堆内存也就是 16M,因此数据大小肯定不能超过这个数字的。其实 sp 设置的目的就是为了保存用户的偏好和配置信息的,因此不要保存太多的数据。
15. Android 的四大组件都需要在清单文件中注册吗?
Activity 、 Service 、 ContentProvider 如 果 要 使 用 则 必 须 在AndroidManifest.xml 中 进 行 注 册 , 而BroadcastReceiver 则有两种注册方式,静态注册和动态注册。其中静态注册就是指在 AndroidManifest.xml 中进行注册,而动态注册时通过代码注册
14. 一条最长的短信息约占多少 byte?
在国内的三大运营商通常情况下中文 70(包括标点),英文 160 个。对于国外的其他运行商具体多长需要看运营商类型了。
android 内部是通过如下代码进行判断具体一个短信多少 byte 的。
ArrayList
13. ddms 和 traceview 的区别
ddms 原意是:davik debug monitor service。简单的说 ddms是一个程序执行查看器,在里面可以看见线程和堆栈等信息,traceView 是程序性能分析器。traceview 是 ddms 中的一部分内容。
12. 请介绍下 adb、ddms、aapt 的作用
adb 是 Android Debug Bridge ,Android 调试桥的意思,
ddms 是 Dalvik Debug Monitor Service,dalvik 调试监视服务。
aapt 即 Android Asset Packaging Tool,在SDK的build-tools目录下。该工具可以查看,创建,更新ZIP格式的文档附件(zip,jar,apk)。也可将资源文件编译成二进制文件,尽管我们没有直接使用过该工具,但是开发工具会使用这个工具打包 apk 文件构成一个 Android 应用程序。
Android 的主要调试工具是 adb(Android debuging bridge),ddms是一个在 adb 基础上的一个图形化工具。
adb,它是一个命令行工具。而 ddms 功能与 adb相同,只是它有一个图形化界面。对不喜欢命今操作方式的人来说是一个不错的选择。
11. 启动应用后,改变系统语言,应用的语言会改变么?
这个一般是不会的,一般需要重启应用才能改变应用语言。但是对应应用来说如果做了国际化处理则支持如果没
有处理那系统语言再更改也是无用的。
10. dvm 的进程和 Linux 的进程,应用程序的进程是否为同一个概念?【2018.1.23更新】
dvm 指 dalvik 的虚拟机。每一个 Android 应用程序都拥有一个独立的 Dalvik 虚拟机实例,应用程序都在它自己的进程中运行。而每一个 dvm 都是在 Linux 中的一个进程,所以说可以近似认为是同一个概念。
什么是 android DVM:Dalvik 是 Google 公司自己设计用于 Android 平台的 Java 虚拟机,每一个 Dalvik 应用作为一个独立的 Linux进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
Dalvik 和 Java 虚拟机的区别
1:Dalvik 主要是完成对象生命周期管理,堆栈管理,线程管理,安全和异常管理,以及垃圾回收等等重要功能。
2:Dalvik 负责进程隔离和线程管理,每一个 Android 应用在底层都会对应一个独立的 Dalvik 虚拟机实例,其代码在虚拟机的解释下得以执行。
3:不同于 Java 虚拟机运行 java 字节码,Dalvik 虚拟机运行的是其专有的文件格式 Dex
4: dex 文件格式可以减少整体文件尺寸,提高 I/O 操作的类查找速度。
5: odex 是为了在运行过程中进一步提高性能,对 dex 文件的进一步优化。
6:所有的 Android 应用的线程都对应一个 Linux 线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
7:有一个特殊的虚拟机进程 Zygote,他是虚拟机实例的孵化器。它在系统启动的时候就会产生,它会完成虚拟机的初始化,库的加载,预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的数据提供给系统。对于一些只读的系统库,所有虚拟机实例都和 Zygote共享一块内存区域。
9. Android 程序与 Java 程序的区别?
Android 程序用 android sdk 开发,java 程序用 javasdk 开发.
Android SDK 引用了大部分的 Java SDK,少数部分被 Android SDK 抛弃
8. 谈一谈 Android 的安全机制
1、Android 是基于 Linux 内核的,因此 Linux 对文件权限的控制同样适用于 Android
在 Android 中每个应用都有自己的/data/data/包名 文件夹,该文件夹只能该应用访问,而其他应用则无权
访问。
2、Android 的权限机制保护了用户的合法权益
如果我们的代码想拨打电话、发送短信、访问通信录、定位、访问 sdcard 等所有可能侵犯用于权益的行为都是必须要在AndroidManifest.xml 中进行声明的,这样就给了用户一个知情权。
3、Android 的代码混淆保护了开发者的劳动成果
7. 谈谈Android的不足和优点
优点:
1、开放性,开源,免费,可定制
2、挣脱运营商束缚
3、丰富的硬件选择
4、不受任何限制的开发商
5、无缝结合的 Google 应用
缺点:
1、安全问题、隐私问题
2、同质化严重
3、运营商对 Android 手机仍然有影响
4、山寨化严重
5、过分依赖开发商,缺乏标准配置
6. Android中进程级别、内存不足时回收顺序?【2018.1.22更新】
1. 空进程(Empty Process)
不包含任何活动应用程序组件,这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间
2. 后台进程(Background process)
不可见状态的activity进程,onstop被调用
3. 服务进程(Service Process)
由 startService() 方法启动的服务,一般都在做着用户所关心的事情,系统会尽量维持它们的运行
4. 可见进程(Visible Process)
activity不在前端显示,但也没有完全隐藏,能够看得见,比如弹出一个对话框
5. 前台进程(Foreground Process)
有正在与用户交互的Activity
5. Android API级别
4. Android工程目录结构
文件(夹)名 | 用途 |
---|---|
.gradleGradle | 编译系统,版本由wrapper指定 |
.idea | Android Studio IDE所需要的文件 |
build | 代码编译后生成的文件存放的位置 |
gradle | wrapper的jar和配置文件所在的位置 |
.gitignore | git使用的ignore文件 |
build.gradle | gradle编译的相关配置文件(相当于Makefile) |
gradle.properties | gradle相关的全局属性设置 |
gradlew | *nix下的gradle wrapper可执行文件 |
graldew.bat | windows下的gradle wrapper可执行文件 |
local.properties | 本地属性设置(key设置,android sdk位置等属性),这个文件是不推荐上传到VCS中去的 |
settings.gradle | 和设置相关的gradle脚本 |
Project目录:
文件(夹)名 | 用途 |
---|---|
.gradleGradle | 编译系统,版本由wrapper指定 |
.idea | Android Studio IDE所需要的文件 |
build | 代码编译后生成的文件存放的位置 |
gradle | wrapper的jar和配置文件所在的位置 |
.gitignore | git使用的ignore文件 |
build.gradle | gradle编译的相关配置文件(相当于Makefile) |
gradle.properties | gradle相关的全局属性设置 |
gradlew | *nix下的gradle wrapper可执行文件 |
graldew.bat | windows下的gradle wrapper可执行文件 |
local.properties | 本地属性设置(key设置,android sdk位置等属性),这个文件是不推荐上传到VCS中去的 |
settings.gradle | 和设置相关的gradle脚本 |
文件(夹)名 | 用途 |
---|---|
build | 编译后的文件存在的位置(包括最终生成的apk也在这里面) |
libs | 依赖的库所在的位置(jar和aar) |
src | 源代码所在的目录 |
src/main | 主要代码所在位置(src/androidTest)就是测试代码所在位置了 |
src/main/assets | android中附带的一些文件 |
src/main/java | 最最重要的,我们的java代码所在的位置 |
src/main/jniLibs | jni的一些动态库所在的默认位置(.so文件) |
src/main/res | android资源文件所在位置 |
src/main/AndroidManifest.xml | AndroidManifest不用介绍了吧~ |
build.gradle | 和这个项目有关的gradle配置,相当于这个项目的Makefile,一些项目的依赖就写在这里面 |
proguard.pro | 代码混淆配置文件 |
Module目录:
文件(夹)名 | 用途 |
---|---|
build | 编译后的文件存在的位置(包括最终生成的apk也在这里面) |
libs | 依赖的库所在的位置(jar和aar) |
src | 源代码所在的目录 |
src/main | 主要代码所在位置(src/androidTest)就是测试代码所在位置了 |
src/main/assets | android中附带的一些文件 |
src/main/java | 最最重要的,我们的java代码所在的位置 |
src/main/jniLibs | jni的一些动态库所在的默认位置(.so文件) |
src/main/res | android资源文件所在位置 |
src/main/AndroidManifest.xml | AndroidManifest不用介绍了吧~ |
build.gradle | 和这个项目有关的gradle配置,相当于这个项目的Makefile,一些项目的依赖就写在这里面 |
proguard.pro | 代码混淆配置文件 |
3. Apk打包流程
1、打包资源文件,生成R.java文件
2、处理aidl文件,生成相应java 文件
3、编译工程源代码,生成相应class 文件
4、转换所有class文件,生成classes.dex文件
5、打包生成apk
6、对apk文件进行签名
7、对签名后的apk文件进行处理
2. DVM 和 JVM 区别
a) dvm 执行的是.dex 文件,而 jvm 执行的是.class。Android 工程编译后的所有.class 字节码会被 dex 工具抽取到一个.dex 文件中。
b) dvm 是基于寄存器的虚拟机 而 jvm 执行是基于虚拟栈的虚拟机。寄存器存取速度比栈快的多,dvm 可以根据硬件实现最大的优化,比较适合移动设备。
c) .class 文件存在很多的冗余信息,dex 工具会去除冗余信息,并把所有的.class 文件整合到.dex 文件中。减少了 I/O 操作,提高了类的查找速度。