android显示,android显示文本内容
Android 从点击应用图标到界面显示的过程
[转] 一篇文章看明白 Android 从点击应用图标到界面显示的过程 (遵循CC 4.0 BY-SA版权协议)
创新互联是一家专业提供肥城企业网站建设,专注与做网站、成都网站制作、HTML5建站、小程序制作等业务。10年已为肥城众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。
从点击桌面应用图标到应用显示的过程我们再熟悉不过了,下面我们来分析下这个过程都做了什么。
本文主要对以下问题分析:
如不了解 Android 是如何从开机到 Launcher 启动的过程,请先阅读 Android - 系统启动过程
我们知道 Android 系统启动后已经启动了 Zygote,ServiceManager,SystemServer 等系统进程;ServiceManager 进程中完成了 Binder 初始化;SystemServer 进程中 ActivityManagerService,WindowManagerService,PackageManagerService 等系统服务在 ServiceManager 中已经注册;最后启动了 Launcher 桌面应用。
其实 Launcher 本身就是一个应用程序,运行在自己的进程中,我们看到的桌面就是 Launcher 中的一个 Activity。
应用安装的时候,通过 PackageManagerService 解析 apk 的 AndroidManifest.xml 文件,提取出这个 apk 的信息写入到 packages.xml 文件中,这些信息包括:权限、应用包名、icon、apk 的安装位置、版本、userID 等等。packages.xml 文件位于系统目录下/data/system/packages.xml。
同时桌面 Launcher 会为安装过的应用生成不同的应用入口,对应桌面上的应用图标,下面分析点击应用图标的到应用启动的过程。
点击 Launcher 中应用图标将会执行以下方法
在 system_server 进程中的服务端 ActivityManagerService 收到 START_ACTIVITY_TRANSACTION 命令后进行处理,调用 startActivity() 方法。
从 Launcher 点击图标,如果应用没有启动过,则会 fork 一个新进程。创建新进程的时候,ActivityManagerService 会保存一个 ProcessRecord 信息,Activity 应用程序中的AndroidManifest.xml 配置文件中,我们没有指定 Application 标签的 process 属性,系统就会默认使用 package 的名称。每一个应用程序都有自己的 uid,因此,这里 uid + process 的组合就可以为每一个应用程序创建一个 ProcessRecord。每次在新建新进程前的时候会先判断这个 ProcessRecord 是否已存在,如果已经存在就不会新建进程了,这就属于应用内打开 Activity 的过程了。
进程创建成功切换至 App 进程,进入 app 进程后将 ActivityThread 类加载到新进程,并调用 ActivityThread.main() 方法
此时只创建了应用程序的 ActivityThread 和 ApplicationThread,和开启了 Handler 消息循环机制,其他的都还未创建, ActivityThread.attach(false) 又会最终到 ActivityMangerService 的 attachApplication,这个工程其实是将本地的 ApplicationThread 传递到 ActivityMangerService。然后 ActivityMangerService 就可以通过 ApplicationThread 的代理 ApplicationThreadProxy 来调用应用程序 ApplicationThread.bindApplication,通知应用程序的 ApplicationThread 已和 ActivityMangerService 绑定,可以不借助其他进程帮助直接通信了。此时 Launcher 的任务也算是完成了。
在 system_server 进程中的服务端 ActivityManagerService 收到 ATTACH_APPLICATION_TRANSACTION 命令后进行处理,调用 attachApplication()。
发送送完 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令,还会发送 BIND_APPLICATION_TRANSACTION 命令来创建 Application。
在 app 进程中,收到 BIND_APPLICATION_TRANSACTION 命令后调用 ActivityThread.bindApplication()。
ApplicationThreadProxy.bindApplication(…) 会传来这个应用的一些信息,如ApplicationInfo,Configuration 等,在 ApplicationThread.bindApplication 里会待信息封装成AppBindData,通过
将信息放到应用里的消息队列里,通过 Handler 消息机制,在 ActivityThread.handleMeaasge 里处理 H.BIND_APPLICATION 的信息,调用 AplicationThread.handleBindApplication。
Instrumentation:
这时 Application 就创建好了,这点很重要,很多资料里说 Application 是在performLaunchActivity() 里创建的,因为 performLaunchActivity() 也有mInstrumentation.newApplication 这个调用,newApplication() 函数中可看出会先判断是否以及创建了 Application,如果之前已经创建,就返回已创建的 Application 对象。
上面 fork 进程时会发送 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令,在 app 进程中,收到 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令后调用 ApplicationThread.scheduleLaunchActivity()。
与 Window 进行关联,具体过程详见: Activity,Window,View 之间的关系
Activity 的整体启动流程如图所示:
Android View显示流程
View显示的关键,是我们如何拿到Canvas。Canvas是由Surface提供的,不同的Canvas实例,决定了显示内容使用软件渲染(cpu)还是硬件渲染(gpu)。SurfaceFlinger则负责将不同Surface对应的不同layer进行图层合并。
所有在同一个ViewGroup中的普通View,都会通过唯一的ViewRootImpl实例向同一个Surface实例获取Canvas。SurfaceView具备独立的Surface,该Surface对应为SurfaceFlinger中独立的layer。他们的显示流程是不同的。
渲染,即生成RGB、YUV等显示器可显示数据的过程。比如上层通过Canvas画一个矩形,最终需要生成一帧数据;给输入视频加特效;输入的是YUV,希望转为RGB显示;甚至输入的就是YUV,但与显示需要的分辨率不一致。这些场景,都需要将渲染后得到的数据放入Surface的显示Buffer中。
多个layer合成,可以通过GLES合成(也叫Client合成或GPU合成),也可以直接通过HWC进行硬件合成(也叫Device合成)。
如何让Android设备实现息屏显示
什么是息屏显示?
息屏显示就是手机在息屏状态下,屏幕上会显示当前时间、日期信息,无需点亮手机屏幕即可查看。息屏显示的原理主要是利用了OLED屏幕像素点自发光的特性,仅显示时间的像素点发光,功耗相比LCD屏幕要低很多。
玩过Android源码的同学应该知道,在Settings里有一个开关项:
既然知道主动显示开关是放在设置里面的,那不妨先从Settings的源码看起,首先找到主动显示对应的Preference,
然后发现在AmbientDisplaySettings里注册了一些controller,
先关注里面的两个:AmbientDisplayNotificationsPreferenceController和AmbientDisplayAlwaysOnPreferenceController,看名字大概能知道,第一个与通知有关,应该是上文提到的息屏后来通知才显示;而第二个就是我们要找的“始终开启”。
AmbientDisplayAlwaysOnPreferenceController :
分析AmbientDisplayAlwaysOnPreferenceController的源码发现,AlwaysOn的enable和available状态都需要通过AmbientDisplayConfiguration 这个类来获得,并且这个类位于framework中。
简单介绍下AmbientDisplayConfiguration 中与alwaysOn有关的几个函数:
alwaysOnAvailable 为true需要同时满足两个条件:
alwaysOnEnabled 为true需要同时满足三个条件:
原来源码里面默认把AlwaysOn功能给关闭了,如果想启用这个功能,需要修改config.xml里的两个值或者强制alwaysOnAvailable返回true,修改后设置里的主动显示一栏就会多出一项“始终开启”可以勾选,这样一来我们的设备在息屏之后就能自动开启主动显示功能了。
以上源码均取自Android O
本文题目:android显示,android显示文本内容
标题路径:http://scjbc.cn/article/dseicgd.html