我是靠谱客的博主 鲜艳灯泡,最近开发中收集的这篇文章主要介绍NO.2 Android 启动,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

零蚀


前言

  • 前言

    • 这段时间我要开始封闭开发了,是项目的重构,最近还有些手上其他项目出现问题(公信部),所以熬夜的时间 越来越长,学习的时间越来越短,终于这个月中旬开始了996的加班模式(加班费也很OK,所以没什么好说的????????????),所以今天完成了手上一个小项目后才想起来有笔记 没有发。

    • 这里我发现首先我的framework的资料并不是 很好,所以这样学必定事半功倍,得不偿失 ,学习方法可能也没认真构思过,所以 我决定改变一下,这不是我想要的framework,并且源代码一点点啃也很耗时(空闲时候慢慢看吧),然后这里我准备 先放下framework的学习,先行开始新的课程《Android逆向工程》。这算是为三,五年计划开篇,嘿嘿。

    • 最后的最后,加油少年,人生就这一次,要活出自己。

启动

  • Activity的启动

    • 根据学习进度,我们先了解一下activity时如何启动的,因为之前我也是遇到一些和应用启动相关的问题,也希望这次能一探究竟, 启动对应的的类是.../packages/apps/Launcher3/src/com/android/launcher3/Launcher.java。这是我们点击应用图标的启动流程。
    // 这里获取了保存启动请求的参数,这个应该是一种反序列化的过程
    // 注释中也提出这是一种跨启动程序实例保存。
    PendingRequestArgs requestArgs = savedState.getParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS);
    // 获取参数后,将里面的类提取出来
    Intent intent = pendingArgs.getPendingIntent();
    ....
    // 获取到手机的权限后,然后启动了activity
    if (grantResults.length > 0
    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    startActivitySafely(v, intent, null);
    }
    ....
    // 开启任务栈准备跳转
    // Prepare intent
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    // 最后进行跳转
    ....
    startActivity(intent, optsBundle);
    
    • 然后这里提示这个startActivity来自Activity.java , 然后我们看过去,大概是下面这个样子,
    public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
    startActivityForResult(intent, -1, options);
    } else {
    // Note we want to go through this call for compatibility with
    // applications that may have overridden the method.
    startActivityForResult(intent, -1);
    }
    }
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
    @Nullable Bundle options) {
    // 如果activity的父控件失是空的
    if (mParent == null) {
    options = transferSpringboardActivityOptions(options);
    Instrumentation.ActivityResult ar =
    mInstrumentation.execStartActivity(
    this, mMainThread.getApplicationThread(), mToken, this,
    intent, requestCode, options);
    if (ar != null) {
    mMainThread.sendActivityResult(
    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
    ar.getResultData());
    }
    if (requestCode >= 0) {
    // If this start is requesting a result, we can avoid making
    // the activity visible until the result is received.
    Setting
    // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
    // activity hidden during this time, to avoid flickering.
    // This can only be done when a result is requested because
    // that guarantees we will get information back when the
    // activity is finished, no matter what happens to it.
    mStartedActivity = true;
    }
    cancelInputsAndStartExitTransition(options);
    // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
    if (options != null) {
    mParent.startActivityFromChild(this, intent, requestCode, options);
    } else {
    // Note we want to go through this method for compatibility with
    // existing applications that may have overridden it.
    mParent.startActivityFromChild(this, intent, requestCode);
    }
    }
    }
    
    • 这里如果父控件为空,也就是说activity父类都还没有创建,这里就会启动一个mInstrumentation.execStartActivity,这个方法中定义了一个ActivityMonitor来监测应用程序和系统的交互。而这个方法,是调用了AMS(ActivityManager .getService ())AMS启动了它里面的startActivity。然后我们来看一下ActivityManagerService,这里面检查了一下启动权限,然后把任务交给了mActivityStarter
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
    Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
    int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
    userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
    profilerInfo, null, null, bOptions, false, userId, null, null,
    "startActivityAsUser");
    }
    
    • 我们一直跟着返回值进行查找,在startActivityUnchecked方法中发现他是对activity的栈进行管理。然后这里调用失败会走ActivityOptions.abort(mOptions)等方法,如果成功任务栈锁定activitymTargetStack.startActivityLocked,当一切正常后进入resumeFocusedStackTopActivityLocked这个方法里面调用了ActivityStack中的resumeTopActivityInnerLocked
    startActivity
    execStartActivity
    startActivity
    startActivity
    Launcher
    Activity
    Instrumentation
    IActivityManager
    AMS
    • 这里我们继续看里面调用了startSpecificActivityLocked方法,这个start方法中又调用realStartActivityLocked这个realstart
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
    System.identityHashCode(r), r.info,
    // TODO: Have this take the merged configuration instead of separate global and
    // override configs.
    mergedConfiguration.getGlobalConfiguration(),
    mergedConfiguration.getOverrideConfiguration(), r.compat,
    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
    r.persistentState, results, newIntents, !andResume,
    mService.isNextTransitionForward(), profilerInfo);
    
    • 这里面调用的thread是IApplicationThread接口对象,这个对象在ApplicationThread extends IApplicationThread.Stub调用,这个AcpplictionThread 是 ActivityThread 类所调用。这个scheduleLaunchActivity方法的调用也是在ActivityThread中实现。

    • 这里就相当于SystemServer进程中的AMS直接和应用进程中的ActicityThread进行了Binder通信。


???? 前言
???? Framework 基础篇
???? NO.1 Android 8.0源码编译 & 启动简介

最后

以上就是鲜艳灯泡为你收集整理的NO.2 Android 启动的全部内容,希望文章能够帮你解决NO.2 Android 启动所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部