android如何开发ui服务,Android UI-对Activity工作流程的理解(一)

概述

在android studio创建一个新项目的时候,或者初学者在刚踏入android开发的时候,都会在首先创建一个MainActivity。根据一般的理解,Activity的就相当于一个界面的入口,所有和界面相关的代码都可以在activity中编写。但是随着经验的增加和项目的深入,不禁要问activity的原理是什么?为什么我们在onCreate()中设置contentView,然后显式或者隐式启动这个activity,就能够在界面上显示,就能够响应用户的点击事件了呢?

其实Activity并不直接是一个能够显示页面的类。在启动时,Activity先通过Binder机制向ActivityServiceManager注册,然后Service通过调用ApplicationThread中的方法向主线程的Handler发送消息,Handler调用ActivityThread中的方法处理activity的创建过程。创建Activity时新建一个DecorView对象,而DecorView正是这个activity界面所有view的根对象。随后,将用户定义的ContentView添加到DecorView中。到这里Activity应该已经创建完成了,但差一个很重要的过程,还没有显示出来!创建以后会继续调用Resume方法,这里会将DecorView注册到WindowManagerService中,然后界面就能接收外界的输入消息了并且显示了。到这里,Activity的视图才最终被用户所看到。页面显示后,系统会将点击事件传递给Activity,用户就可以与Activity视图进行交互了。

那么如何开始我们的启动之旅呢。首先,我们先了解下android系统的架构,相信很多人在刚开始学的时候就已经看过这个框架。我们先看一下系统的framework层和我们应用之间的关系,先有一个整体的概念。其次,应用启动的时候,都会启动一个dalvik虚拟机,然后运行应用的主线程,然后再去加载我们的activity,我们就一步一步去跟踪Activity'的启动流程。所以这一篇先介绍framework层,再介绍如何看源码。具体的activity实现流程等到以后的博客中再去分析。

应用与framework层的关系

android框架

相信大家都对这张框架图不陌生,从整体框架来看,主要分为Linux内核层,库和运行时层,framework层和应用层。以本人的能力,当然无法讲解整个体系,只是说一下framework层和应用的联系的一点理解。

c1847dc42aaa?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Paste_Image.png

android framework层

我们观察framework层的各个子模块,会发现一个共同点,他们都是以manager、service、provider结尾的。这让我们想到了framework层的作用大概是提供服务或者管理用的层。因为系统会通过各种manager管理我们的应用,也会向我们提供各种服务,所以我们猜测,那么我们在创建应用或者创建activity时,必然会和各种framework层的模块打交道。

系统service的启动

在Android启动过程中,系统会启动各种framework层的服务。所以来看下SystemServer这个类。从名字可以看出它提供了系统运行时所需要各种java编写的“系统服务”。

public static void main(String[] args) {

new SystemServer().run();

}

public SystemServer() {

// Check for factory test mode.

mFactoryTestMode = FactoryTest.getMode();

}

private void run() {

...

// Start services.

try {

//启动引导服务

startBootstrapServices();

//启动核心服务

startCoreServices();

//启动另外一些服务

startOtherServices();

} catch (Throwable ex) {

throw ex;

}

...

// Loop forever.

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");

}

在启动引导和核心服务的方法中会启动如下一些service和manager

private PowerManagerService mPowerManagerService;

private ActivityManagerService mActivityManagerService;

private DisplayManagerService mDisplayManagerService;

private PackageManagerService mPackageManagerService;

private PackageManager mPackageManager;

在启动另外的服务时会启动如下一些service(没有列全)

NetworkManagementService networkManagement = null;

ConnectivityService connectivity = null;

WindowManagerService wm = null;

InputManagerService inputManager = null;

TelephonyRegistry telephonyRegistry = null;

AudioService audioService = null;

CameraService cameraService = null;

系统service与应用如何交互

看到这些名字,我们都会感觉很熟悉,因为在写应用的时候,经常或通过java context.getSystemService(Context.ACTIVITY_SERVICE);这样的方法去拿到系统的服务。其实,我们并不是拿到了正真的系统服务,因为系统服务并不是在我们应用所在的进程中运行,所以我们拿到的是系统服务的入口对象。如下代码所示,最终我们会在SystemServiceRegistry中获得一个ActivityManger对象。Activity对象中通过ActivityManagerNative.getDefault()这个Binder对象来与系统服务进行通信。(关于Binder,后续会给一个大致的介绍,这边主要讲framework与应用的关系,所以不再继续深入下去)。

SystemServiceRegistry{

...

static{

...

registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,

new CachedServiceFetcher() {

@Override

public ActivityManager createService(ContextImpl ctx) {

return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());

}});

...

}

}

那么我们讲了这么多,有什么用呢。其实activity的启动与framework有莫大的联系,如果没有系统服务,那么我们的进程就无法显示,activity就无法创建,view就无法绘制,滑动点击事件也无法传递给应用,说到底,我们的应用构建在系统服务至上。在后续的介绍中,会着重去跟踪几个系统服务的类,所以说先在开始时从宏观上介绍一下我们到底和谁在通信,为什么要通信。

关联相应的源码

目前android studio是主流的android 开发软件,一般在android应用创建以后,会关联默认的android部分源码。如果希望获得其他版本的源码,可以通过SDK Manager进行下载。我使用的是android-23的源码。

c1847dc42aaa?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Paste_Image.png

如何调试Studio源码

点击菜单栏的“Run”->“Attach debugger to Android process”,选择需要调试的进程。然后再源码上加断点,debug就可以断在相应的位置。如果开始attach到app的进程,则看不到系统应用的进程的断点。如果需要调试ActivityMangerService这样的系统服务类的话,那么需要attach到system_process,然后对自己的应用进行断点调试。

c1847dc42aaa?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Paste_Image.png

如上图所示,我们算是成功的进行了断点。

总结

这里我们介绍了framework层和activity的关系,简单说了下如何调试源码。接下去,会介绍线程及线程入口,及android非常重要的looper机制。这也是理解activity运行机制的非常重要的一部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值