黑马程序员技术交流社区
标题: 【济南校区】凯哥兵法之Android知识总结篇(一) [打印本页]
作者: 孟凡凯老师 时间: 2016-6-10 17:49
标题: 【济南校区】凯哥兵法之Android知识总结篇(一)
本帖最后由 孟凡凯老师 于 2016-6-10 17:47 编辑
【济南校区】凯哥兵法之Android知识总结篇(一)
前言:
这两天闲来无事逛了逛各大网络论坛,突然发现了这么一篇帖子---[Android基础]Android总结篇,本着独乐乐不如众乐乐的态度,对原文进行了一些修改,并分享给大家, 原文链接见:http://blog.csdn.net/codeemperor/article/details/51004189。
1. Android架构
Android的系统架构和其他操作系统一样,采用了分层的架构。Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。
1.Applications(应用程序层)
用户就是通过编写好的应用程序与Android 手机交互,或者可以说用户就是通过这些程序来操控Android 设备。这些应用程序在设备上都是以一个小图标来表示,用户通过单击图标来运行程序。Android 系统一般内置有Email、短信收发程序、浏览器、联系人等功能的应用程序。除了内置的应用程序外,开发者可以编写更多的应用程序,让用户可以使用更多便利的功能。
2.Application Framework(应用程序框架层)
ApplicationFramework 其实就是Android 的API(Application Programming Interface),开发者只要善用此API 即可快速开发出Android 应用程序。包含一些比较重要的服务View System(用户界面),Activity Manager(活动管理器)、Content Providers(内容提供器)、Resource Manager(资源管理器)、Notification Manager(信息管理器)。
3.Libraries(函数库)
Libraries里面包含程序库和运行环境,
其中程序库是一个内部函数库,此函数库主要以C/C++编写而成。Android 应用程序开发人员并非直接使用此函数库,而是通过更上层的应用程序框架(Application Framework)来使用此函数库功能,所以有人称此类函数库为原生函数库(Native Libraries)。此函数库依照功能又可细分成各种类型的函数库,比如:Media Framework(媒体函数库)、Surface Manager(外观管理函数库)、WebKit、SGL、OpenGL|ES、SQLite。
AndroidRuntime 可分成AndroidCore Libraries(Android 核心函数库)与DalvikVirtualMachine(Dalvik VM,Dalvik 虚拟机)。Android核心函数库提供了JAVA编程语言核心库的大多数功能。每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK中 的"dx" 工具转化成.dex格式由虚拟机执行。Dalvik虚拟机依赖于linux内核的一些功能,比如线程机制和底层内存管理机制。
4.Linux 内核
Android以Linux 2.6 版作为整个操作系统的核心,Linux 提供Android 主要的系统服务如:安全性管理(Security)、内存管理(Memory Management)、进程管理(Process Management)、网络栈(Network Stack)、驱动模型(Driver Model)、电源管理(Power Management)等。
2.Android系统启动过程,App启动过程App启动过程:
1.启动linux内核内核会记载各种数据结构,和驱动程序,加载完毕之后开始启动并加载第一个用户级别的进程:init(system/core/init/Init.c)
2. init.c 加载linux文件系统 相关服务
- init_parse_config_file("/init.rc");
复制代码 init.rc里 最关键的
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
复制代码 以服务的形式把zygote启动,
3.App_main.cpp ->AndroidRuntime.cpp start函数
创建了一个java虚拟机 注册并通过jni 反射调用zygoteInit.java 的main方法
4.zygoteInit.java main方法
① // 创建一个socket服务端(ServerSocket实例) 用来等待 ActivityManagerService请求zygote进程创建新的应用程序进程
registerZygoteSocket(); //到这里 zygote就创建完成了
②//启动系统服务进程
if (argv[1].equals("start-system-server")) {
startSystemServer(); //启动服务
5.系统服务进程创建之后 调用SystemServer.java main函数
在main函数中创建了一个ServerThread();加载动态链接库--android_servers,执行init1()(开启Native世界)-(ServerThread启动执行init2()开启ServerThread ,并调用ServerThread()的run方法
Looper.prepareMainLooper();
//启动了大量的系统服务并且添加到 ServiceManager中
创建了ActivityManagerService
6. 调用systemReady准备创建第一个activity如果ActivityManagerService准备好了就检查任务栈中是否有activity如果没有就启动luncher
zygote:
zygote 在android系统中,所有的应用程序进程,用来运行关键系统服务的System进程 都是由 zygote进程负责创建的,所以我们管它叫孵化器进程(直接翻译是受精卵的意思),zygote进程是通过复制自身的方式来创建系统进程 和应用程序进程的. 由于zygote进程在创建时会在内部创建一个虚拟机的实例,所以复制自身的时候就会复制出一个新的虚拟机实例来. 那么通过这种方式 就可以很快的为新的进程创建一个虚拟机 在zygote进程中有一个socket服务端 activity manager service 通过socket告诉zygote 复制一个新的进程 这个进程就用来作为新创建的应用进程。
从桌面点击到activity启动的过程:
1、Launcher线程捕获onclick的点击事件,调用Launcher.startActivitySafely,进一步调用Launcher.startActivity,最后调用父类Activity的startActivity。
2、Activity和ActivityManagerService交互,引入Instrumentation,将启动请求交给Instrumentation,调用Instrumentation.execStartActivity。
3、调用ActivityManagerService的startActivity方法,这里做了进程切换(具体过程请查看源码)。
4、开启Activity,调用onCreate方法
3.ART和Dalvik区别
art上应用启动快,运行快,但是耗费更多存储空间,安装时间长,总的来说ART的功效就是”空间换时间”。
ART: Ahead of Time Dalvik: Just in Time
什么是Dalvik:Dalvik是Google公司自己设计用于Android平台的Java虚拟机。Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一,它可以支持已转换为.dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik应用设计的一种压缩格式,适合内存和处理器速度有限的系统。Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik应用作为独立的Linux进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
什么是ART:Android操作系统已经成熟,Google的Android团队开始将注意力转向一些底层组件,其中之一是负责应用程序运行的Dalvik运行时。Google开发者已经花了两年时间开发更快执行效率更高更省电的替代ART运行时。ART代表Android Runtime,其处理应用程序执行的方式完全不同于Dalvik,Dalvik是依靠一个Just-In-Time(JIT)编译器去解释字节码。开发者编译后的应用代码需要通过一个解释器在用户的设备上运行,这一机制并不高效,但让应用能更容易在不同硬件和架构上运行。ART则完全改变了这套做法,在应用安装的时候就预编译字节码到机器语言,这一机制叫Ahead-Of-Time(AOT)编译。在移除解释代码这一过程后,应用程序执行将更有效率,启动更快。
ART优点:
- 系统性能的显著提升
- 应用启动更快、运行更快、体验更流畅、触感反馈更及时。
- 更长的电池续航能力
- 支持更低的硬件
ART缺点:
- 更大的存储空间占用,可能会增加10%-20%
- 更长的应用安装时间
4.Android几种进程
- 前台进程: 即与用户正在交互的Activity或者Activity用到的Service等,如果系统内存不足时前台进程是最后被杀死的
- 可见线程:可以是处于暂停状态(onPause)的Activity或者绑定在其上的Service,即被用户可见,但由于失去了焦点而不能与用户交互
- 服务进程:其中运行着使用startService方法启动的Service,虽然不被用户可见,但是却是用户关系的,例如用户正在非音乐界面听的音乐或者正在非下载页面自己下载的文件等,当系统要用空间运行前两者进程时才会被终止
- 后台进程:其中运行着执行onStop方法而停止的程序,但是却不是用户当前关心的,例如后台挂着的QQ,这样的进程系统一旦没有内存就首先被杀死。
- 空进程:不包含任何应用程序的程序组件的进程,这样的进程系统是一般不会让他存在的。
如何避免后台进程被杀死?
- 调用startForegound,让你的Service所在的进程成为前台进程
- Service的onStartCommand返回START_STICKY或START_REDELIVER_INTENT
- Service的onDestroy里面重新启动自己
5.Activity和Service的生命周期常见的例子:程序正运行着来电话了,这个程序咋办呢?中止了呗,如果中止的时候新出的一个Activity是全屏的onPause->onStop,恢复的时候onStart->onResume,如果打断这个应用程序的是一个Theme为Translucent或者Dialog的Activity那么只是onPause,恢复的时候onResume。
- onPause:恢复的时候onResume
- onCreate:在这里创建界面,做一些数据的初始化工作
- onStart:到这一步变成用户可见不可交互的
- onPause:到这一步是可见但不可交互的,系统会停止动画等消耗CPU的事情,应该在这里保存你的一些 数据,因为这个时候你的程序的优先级降低,有可能被 系统回收。在这里保存的数据,应该在onResume里读出来。注意:这个方法里做的事情时间要短,因为下一个Activity不会等到这个方法完成才启动。
- onStop:变得不可见,被下一个Activity覆盖了(onPause和onStop的区别是否可见)
- onDestroy:这是Activity被干掉前最后一个被调用方法了,可能是外面类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有一个ProgressDialog在线程中转动,请在onDestroy里把它cancel掉,不然等线程结束的时候,调用Dialog的cancel会抛出异常的。
onPause,onstop,onDestroy,三种状态下,Activity都有可能被系统干掉。
启动另一个Activity然后finish,先调用旧Activity的onPause方法,然后调用新的Activity和onCreate->onStart->onResume方法,然后调用旧Activity的onStop->onDestroy方法。
如果没有调用finish那么onDestroy方法不会被调用,而且在onStop之前还会调用onSavedInstanceState方法
onRestart方法执行完了之后还会调用onStart方法
service生命周期:
startService()生命周期onCreate()--> onStartCommond()-->onDestroy();
bindService()生命周期onCreate()-->onBind()-->onUnBind()-->onDestroy();
6.Service和Thread的区别Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作,Thread的运行是独立于Activity的,也就是说当一个Activity被finish之后,如果你没有主动停止Thread或者Thread里的run方法没有执行完毕的话,Thread就会一直执行。
Service:Service 是android的一种机制,当它运行的时候如果是LocalService,那么对应的Service是运行在主进程的main线程上的。如onCreate,onStart这些函数都是在系统调用的时候在主进程的main线程上运行的。如果是RemoteSevice,那么对应的Service则是运行在独立的main线程上。
- 服务不是单一的进程,服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中
- 服务不是线程,可以在线程中工作
- 在应用中,如果是长时间的在后台运行,而且不需要交互的情况下,使用服务
- 同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需要长时间运行的情况下使用线程
- 如果任务占用CPU时间多,资源大的情况下,要使用线程
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |