Android应用运行过程(转)

源:Android应用运行过程

首先,ActivityThread从main()函数开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue)。

然后创建一个ActivityThread对象,在ActivityThread的初始化代码中会创建一个H(Handler)对象和一个ApplicationThread(Binder)对象。其中Binder负责接收远程AmS的IPC调用,接收到调用后,则通过Handler把消息发送到消息队列中,UI主线程会异步的从消息队列中取出消息并执行相应的操作,比如start  stop pause等。

接着UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断的从消息队列中读取并处理消息。

当ActivityThread接收到AmS发送start某个Activity后,就会创建指定的Activity对象,Activity又会创建PhoneWindow类——>DecorView类——>创建相应的View或者ViewGroup。创建完成后,Activity需要把创建好的界面显示到屏幕上,于是调用WindowManager类,后者于是创建一个ViewRoot对象,该对象实际上创建了ViewRoot类和W类,创建ViewRoot对象以后,WindowManager再调用WmS提供的远程调用接口完成添加一个窗口并显示到屏幕上。

继续往下看,attach方法会通过代码mWindow = PolicyManager.makeNewWindow(this)实例化一个phoneWindow对象

PolicyManager的作用可参看博主的

android的Policymanager 作用

然后接下来就是在activity开始onCreate调用时,会调用PhoneWIndow的setContentView方法, 当然这里有是否第一次的判断,然后调用方法installDecor(), 再调用generateDecor() 创建顶层视图 DecorView mDecor,DecorView是FrameLayout的子类;在方法generateLayout(mDecor)  中 会干些什么事儿呢?

该方法会做如下事情:(不想写了,在qinjuning的blog中copy了一下,谅解呀)
   1、根据窗口的风格修饰类型为该窗口选择不同的窗口布局文件(根视图)。这些窗口修饰布局文件指定一个用来存放
         Activity自定义布局文件的ViewGroup视图,一般为FrameLayout 其id 为: android:id="@android:id/content"。
        例如窗口修饰类型包括FullScreen(全屏)、NoTitleBar(不含标题栏)等。选定窗口修饰类型有两种:
           ①、指定requestFeature()指定窗口修饰符,PhoneWindow对象调用getLocalFeature()方法获取值;
           ②、为我们的Activity配置相应属性,即android:theme=“”,PhoneWindow对象调用getWindowStyle()方法
              获取值。
        举例如下,隐藏标题栏有如下方法:requestWindowFeature(Window.FEATURE_NO_TITLE);
                   或者 为Activity配置xml属性:android:theme=”@android:style/Theme.NoTitleBar”。
 
        PS:因此,在Activity中必须在setContentView之前调用requestFeature()方法。
  确定好窗口风格之后,选定该风格对应的布局文件,这些布局文件位于 frameworks/base/core/res/layout/  ,
        典型的窗口布局文件有:
          R.layout.dialog_titile_icons                          R.layout.screen_title_icons
          R.layout.screen_progress                             R.layout.dialog_custom_title
          R.layout.dialog_title   
          R.layout.screen_title         // 最常用的Activity窗口修饰布局文件
          R.layout.screen_simple    //全屏的Activity窗口布局文件

到最后了,ActivityManagerService准备resume一个Activity时,会回调该Activity的handleResumeActivity()方法,再调用Activity的makeVisible方法 ,显示创建的DectorView

下面是一些总结信息:

windowManager只是提供接口,用了桥接模式,真正实现是WindowManagerImpl类。而调用addiew方法的对象来自另一个类LocalWindowManager,它会做一些简单检查,再通过WindowManagerImp类的addview完成窗口添加。addview大概分三步执行:

1.校验该窗口是否已经添加过了。

2.判断窗口类型如果是子窗口,则找到它附属的父窗口

3.new一个ViewRootImpl对象,最后调用该对象的setView方法。

setView 方法会最终会通过ipc调用IwindowSession的add方法。Session类实现了该方法,并最终给WindowManagerService处理。客户端的工作至此就完成了。

这里说明一下ViewRootImpl类,这其实是个handler。自然的,它一部分功能就是对消息进行处理,将用户的一些操作分发到view中。它也是view和WindowManagerService的桥梁。可以看到它通过一个会话将信息传递到了WindowManagerService。而WIndowManagerService也会通过IWindow接口将指令通过消息的方式发送到ViewRootImpl,ViewRootImpl处理这些消息。

二.服务端

WindowManagerService的addWindow方法主要做三部分的处理。

1.做一些合法性校验

2.完成窗口数据的构建

3.完成窗口创建后需要作出的一些调整

我们只看第二部分。首先会new一个WindowState类,该类表示一个窗口。结合WindowToken和AppWindowToken,完整的定义了一个窗口内容。接着创建一个管道,用于处理消息输入。再然后调用attach方法,创建和Surface相关的内容,用于和surfaceFlinger交互。这样,整个窗口就搭建完成了。有了WindowState类对窗口属性的保存以及token对窗口归属的标识,之后就可以通过SurfaceFlinger绘制在屏幕上了。之后通过InputManager,也能处理消息和WindowManagerService之间的传递。保证窗口显示内容和用户操作保持一致性。

当然,WindowManagerService靠近10000行的代码完成了很多功能,因为这篇文章只会了解窗口管理的整个架构,这里不一一详解,以后有时间可能会把一些比较有意思的内容再看下:

1. 窗口的创建和删除

2. 窗口的显示和隐藏控制

3. Z-order顺序管理

4. 焦点窗口管理

5. 输入法窗口管理和墙纸窗口管理

6. 切换动画

7. 系统消息收集和分发、

接下来,用户开始在程序界面上操作,KeyQ线程不多把用户消息存储到QueueEvent队列中,InputDispatcherThread线程逐个取出消息,然后调用WmS中的相关函数处理该消息,当WmS发现该消息属于客户端某个窗口时,就会调用相应的窗口W接口。

W类是一个Binder,负责接收WmS的IPC调用,并把调用消息传递给ViewRoot,ViewRoot再把消息传递给UI主线程ActivityThread,ActivityThread解析该消息并作相应的处理,在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理该消息,则可以把该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后在传递给Activity。

一个应用中有哪些线程?

首先,我们都知道的UI线程即用户交互线程,用来处理用户消息和界面绘制;

其次,每个Binder对象对应一个线程;在ActivityThread中会创建ApplicationThread,他们都是继承Binder,这里会启动两个线程;

所以最少应该是3个线程.....然后开发人员自定义的子线程.....待续。

时间: 2024-08-13 15:30:11

Android应用运行过程(转)的相关文章

android的编译和运行过程深入分析

android的编译和运行过程深入分析 作者: 字体:[增加 减小] 类型:转载 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,此过程对了解android的编译和运行过程有很大的帮助 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,示意图如下,其中包含编译.链接和签名等: (1)使用aapt工具生成R.java文件 可以先通过搭建好的Eclipse开发环境创建一个未编译的Android工程,记的一定要将Eclipse中Proj

Android ART运行时与Dalvik虚拟机

这几天在做一个项目时需要在Android中使用OSGi框架(Apache Felix),于是在一个android 4.4.2 版本系统的某品牌的平板上实验. 实验内容很简单:把felix包里的felix.jar包和一些bundles的jar包用android sdk里的dx及aapt工具转化为包含dex字节码的jar 包.这样使这些jar包能在Android上跑起来.(因为Android上使用的是在Dalvik虚拟机而不是标准的java虚拟机,所以“原生”的 jar包不能直接在Android上跑

appium界面运行过程(结合日志截图分析)

appium界面运行过程: 1.启动一个http服务器:127.0.0.1:47232.根据测试代码setUp()进行初始化,在http服务器上建立一个session对象3.开始调用adb,找到连接上的设备,设置设备id4.等待设备准备好响应命令5.开启logcat日志监控6.将生成的apk属性信息文件strings.json存到了设备 /data/local/tmp目录下7.读取apk安装情况8.端口映射,发给appium httpserver的内容,经过httpserver后直接发给设备 f

android app启动过程(转)

Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启动,启动的过程如下: Shell接收到命令,启动一个程序,此时shell首先会fork一个新的进程 新fork的进程,通过execve系统调用,陷入到内核中,内核检查和加载需要执行的二进制映像文件,检验其合法性及权限.通常用户态进程要启动一个新的程序(如shell),fork后,execve要紧跟着

Android模拟器运行慢的解决方案

在android开发的过程,发现android模拟器的速度不是一般的慢,那主要是因为android模拟器默认采用的是arm处理器造成的,这里主要提供两种方法: ① 利用intel虚拟硬件加速的方式,实现android模拟器的加速,从而解决android模拟器速度慢的问题: ② 使用genymotion模拟器, 主要采用的是利用Virtual Box虚拟机的原理: 软件的百度云链接:http://pan.baidu.com/s/1i39oLXr 密码:5t0f 采用Haxm技术 1. 1).重新启

老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1

老李推荐: 第8章4节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-启动AndroidDebugBridge 上一节我们看到在启动AndroidDebugBridge的过程中会调用其start方法,而该方法会做2个主要的事情: 715行startAdb:开启AndroidDebugBridge 722-723行:初始化android设备监控并启动DeviceMonitor设备监控线程. 其中第一点我们上一小节已经做了详尽分析了,那么我们往下就去分析下第2点. Dev

Android APK安装过程学习笔记

1.什么是APK APK,即Android Package,Android安装包.不同平台的安装文件格式都不同,类似于Windows的安装包是二进制的exe格式,Mac的安装包是dmg格式.APK可以再Android上执行安装,APK的本质是一个Zip压缩包,只是后缀被修改为apk,其中打包了源代码编译出的class.dex.一些图片视屏资源文件和一些Native库文件.APK文件与Zip文件最大的一个不同是APK包含签名文件,用于保证安装包安全不被修改. 2.什么是DEX文件和ODEX文件 J

Android应用构建过程解析

要得心应手地进行Android应用开发需要我们对Android工程的编译和打包有一个比较深入的理解,例如知道它的每一步都做了什么,需要什么环境和工具,输入和输出是什么,等等. 在前文<命令行下Android应用开发>中我们已经知道如何创建一个Android工程和编译运行可调试版本的应用程序.本文将介绍Android工程的整个编译过程. 首先来分析Ant如何将Android工程编译打包成APK文件 执行ant debug命令时ant 脚本build.xml各target之间的依赖关系图 执行an

Android的init过程详解(一) 转

本文使用的软件版本 Android:4.2.2 Linux内核:3.1.10 本文及后续几篇文章将对Android的初始化(init)过程进行详细地.剥丝抽茧式地分析,并且在其中穿插了大量的知识,希望对读者了解Android的启动过程又所帮助.本章主要介绍了与硬件相关初始化文件名的确定以及属性服务的原理和实现. Android本质上就是一个基于Linux内核的操作系统.与Ubuntu Linux.Fedora Linux类似.只是Android在应用层专门为移动设备添加了一些特有的支持.既然An