欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SystemServer到Launcher

程序员文章站 2022-06-30 16:33:14
...

通过前面对android 启动流程到SystemServer的分析,紧接着我们来到了本篇博客,介绍从 systemserver 到 launcher 的启动过程。

整体过程

SystemServer到Launcher
从 SystemServer 到 Launcher 的过程其实就是从系统进程到应用进程的过程,他们之间通过binder通信来传递信息,并相互作用一起决定桌面应用(launcher)的启动。

整体流程图

SystemServer到Launcher
上图详细介绍了从 systemserver.run 方法通过层层调用,最终将桌面应用程序launcher运行起来的过程。

重要基础知识点

Binder

SystemServer到Launcher

可参考连接:http://www.jianshu.com/p/af2993526daf

简单点理解如下:

  1. Linux中存在进程隔离,用户空间中的进程不能相互访问,用户空间可以通过系统调用这个统一接口访问内核控件,系统调用时由内核控件运行。
  2. binder是一个IPC通信机制,Linux通过动态可加载内核模块机制,将binder驱动加载进了内核,内核具有访问所有进程资源的权限,android端的进程就可以通过binder驱动来跨进程访问。
  3. binder具有性能高而且较安全的优点,所有没有使用socket和管道子类的IPC通信机制。
  4. 两个运行在用户空间的进程要完成通信,必须借助内核的帮助,这个运行在内核里面的程序叫做Binder驱动,它的功能类似于基站;通信录呢,就是一个叫做ServiceManager的东西(简称SM)。
  5. sever向SM注册信息:数据流会通过binder驱动,所以binder驱动会对数据做点处理,此时,SM中存储的是server的代理对象。
  6. client向SM查询信息:同上,binder会给client返回一个objectProxy代理对象。所以client只是持有了server端的代理对象,代理对象和binder同时工作,完成了IPC通信。
  7. 在驱动中,Binder本地对象的代表是一个叫做binder_node的数据结构,Binder代理对象是用binder_ref代表的。
  8. 一个需要跨进程传递的对象一定继承自IBinder,如果是Binder本地对象,那么一定继承Binder实现IInterface(Stub对象),如果是代理对象,那么就实现了IInterface并持有了IBinder引用(Proxy对象)。
  9. 相当于server和client端都有XXX.aidl文件和编译器生成的XXX.java文件,其中真正其作用的是XXX.java文件,这个文件里面有一个Stub对象,代表的是binder本地对象,还有一个Proxy对象,代表的是binder代理对象,当通过asInterface方法时,会先在本进程搜索你要访问的对象是不是binder本地对象,如果是,则强制类型转换并返回,代表没有跨进程访问直接调用本进程方法,如果不是,则返回一个Proxy代理对象,然后使用Proxy通过binder驱动,调用远端server的Stub对象的相关方法,这里就进行了IPC访问。
  10. 一般Stub对象都会有一个继承它的类,并实现server中具体的方法。

AIDL

aidl 是基于binder通信机制来完成跨进程访问。参考: http://blog.csdn.net/luoyanglizi/article/details/51980630

简单理解如下:

在服务端进程:

  1. 创建一个XXX.aidl为后缀的文件,并定义具体方法的接口,然后IDE就会自动生成一个同名的XXX.java文件。
  2. 创建一个service在onBind的时候返回一个IBinder的对象,这个对象是刚才创建的接口对象的代理,private final XXX.Stub mBinder = new XXX.Stub()并实现里面的接口方法

在客户端进程:

  1. 先将服务端的XXX.aidl文件,copy到与服务器相同包路径下面 ,clear一下或者rebuild一下会自动生成XXX.java的文件。
  2. 通过bindService和ServiceConnection 连接到服务端进程。
  3. ServiceConnection.onServiceConnected 中通过XXX.Stub.asInterface(service) 得到 XXX.java对象。
  4. 通过 XXX 对象调用服务端的具体代码实现

反射

还不太了解,后续补上。

流程中的重要内容

systemserver的run方法里面

startBootstrapServices

开启一些引导服务,包括如下内容:

  • Installer.class 获取权限并创建一些路径如:/data/user
  • ActivityManagerService.Lifecycle.class设置SystemServiceManager、Installer、PowerManagement等
  • PowerManagerService.class 负责协调设备电源管理,其他服务依赖于它
  • LightsService.class 负责LED和背光显示
  • DisplayManagerService.class 控制界面的显示
  • RegionalizationService 区域服务
  • UserManagerService.LifeCycle.class
  • startSensorService 开始sensor服务

startCoreServices

开启一些之前没有打开的核心服务,包括如下:

  • BatteryService.class 电池电量服务
  • UsageStatsService.class 收集应用程序数据
  • WebViewUpdateService.class webview更新服务

startOtherServices

启动一些其它的服务并调用一些核心的放,这里面涉及到的东西就比较多了,下面列举部分,读者可以自行查看源码。
TelecomLoaderService.class、TelephonyRegistry、CameraService.class、AlarmManagerService.class、 watchdog.init、WindowManagerService、InputManagerService、BluetoothService.class、AccessibilityManagerService、StatusBarManagerService、NetworkStatsService、WifiService 等等还有很多。。。。。。

ActivityManagerService

得到要启动界面launcher.java的action 和 category

    Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); //android.intent.action.MAIN 获取需要启动的activity
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME); //android.intent.category.HOME
        }
        return intent;
    }

ActivityStack

通过binder实现systemserver和应用进程的通信

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean dontWait) {
            .....省略部分代码
                    if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev, false);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);//通过binder通信调用ActivityThread.schedulePauseActivity 执行当前界面activity 的onPause 方法。
            }
            .....省略部分代码
            }

ActivityThread

通过binder实现应用进程和systemserver的通信

    private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
            .......省略部分代码
            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);//通过binder通信调用 ActivityManagerService.activityPaused 通知activity pause完成
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

ActivityStackSupervisor

直接启动activity或者创建进程

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
            .....省略部分代码
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);//如果要启动的activity所属进程已启动,那么直接启动activity
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);//如果activity所属进程没有启动,那么先创建该进程
    }

ActivityThread

创建当前进程的主线程

public static void main(String[] args) {
        .....省略部分代码

        Looper.prepareMainLooper();//创建消息队列

        ActivityThread thread = new ActivityThread(); //创建主线程
        thread.attach(false);
        .....省略部分代码
        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();//开启消息循环

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

会执行到activity的onCreate、onResume等方法

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
         ......省略部分代码
        Activity a = performLaunchActivity(r, customIntent);//最终会执行activity的onCreate方法

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); //最终会执行activity的onResume方法
        ......省略部分代码
    }

参考:http://blog.csdn.net/qq_23547831/article/details/51224992

相关标签: launcher