IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 1-APP启动源码分析-1 -> 正文阅读

[移动开发]1-APP启动源码分析-1

桌面app也就是我们认识的launcher app,点击app icon启动到app内部的过程分为2种情况,一种是冷启动,一种叫热启动。

冷启动:系统没有创建过app的进程,也就是后台没有此app进程,所以冷启动系统会创建一个新的进程分配给app,再创建application类,最终再创建根activity并显示UI。

热启动:之前进行过冷启动但最终退出了该app,此时app的进程还在后台,在app进程存在的情况下启动app为热启动,此时不需创建application,只需创建根acticity即可。

分析App的启动,冷启动的过程的步骤是多于热启动,热启动少了创建application的步骤,所以我们先从冷启动开始分析。

1,桌面点击app图片,触发app启动流程

Launcher.java
public boolean startActivitySafely(View v,Intent intent,ItemInfo item){
...
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//你懂的,activity要在新的任务栈中启动
...
startActivity(itent,optsBundle);//此时还在Launcher app的进程中,此时的代码和普通activity间的跳转已经大体一样了
                                //不一样在于普通activity的startActivity是在app自己的进程中,冷启动是在Launcher进程中
}

2,activity的startActivity(Intent)分析

1,Activity.java

@Override
    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);
        }
    }

2,看下startActivityForResult()
 Activity.java

     public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {//此时根activity还没创建,此时肯定为null
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( //关键代码,mInstrumentation号称Android中一些列控制方法的集合,可以在正常生命周期之外控制Android控件的运行
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
           ...
        } else {
           ...
        }
    }

3,mInstrumentation.execStartActivity()
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
分析:ActivityTaskManager.getService()得到的是IActivityTaskManager,也就是AMS的代理对象,接着调用它的startActivity

4,看下ActivityTaskManager
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);//得到AMS的引用
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);//返回IActivityManager的对象,使用AIDL,要实现进程间通信,只要AMS实现IActivityManager即可
                    return am;
                }
            };


总结:经过上面的多层中转,实现了请求从Launcher进程过渡到AMS中

下面看下AMS在收到Launcher的Binder指令后做了什么操作

1,为了实现进程间通信,AMS是继承自IActivityManager.Stub的
public class ActivityManagerService extends IActivityManager.Stub{
...
}

2,实际的startActivity
ActivityManagerService.java

 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,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")  //obtainStarter()返回ActivityStarter
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

3,ActivityStarter类,见名知义,负责activity的启动操作,关键跳转到startActivityMayWait()
    ActivityStarter.java

 private int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
        ...
        //获取ResolveInfo信息 有的时候隐式跳转可以有多个Intent可选,会在此时弹出选择框
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                0 /* matchFlags */,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, mRequest.filterCallingUid));
        ...
        //获取目标activity的信息
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
          //启动activity
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);


            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }    

4,startActivity()中实际执行方法
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ...
        computeLaunchingTaskFlags();//计算启动的Activity的Flag值
        ...
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,mOptions);//处理task和activity的进出栈操作
        ...
          mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);//启动栈顶activity
        ...     
    return START_SUCCESS;
    }


5,最终一路跳转,创建启动activity事务,交给AMS启动Activity 这一系列涉及process相关的方法其实是通过zygote创建进程
ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        if (app != null && app.thread != null) {
            try {
               realStartActivityLocked(r, app, andResume, checkConfig);//启动activity事务
                return;
            } catch (RemoteException e) {
            }
        }
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);//执行activity启动
    }


 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {  
                // Create activity launch transaction.创建activity启动事务
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,//传入app的线程,也就是ApplicationThread
                        r.appToken);
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        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, mService.isNextTransitionForward(),
                        profilerInfo));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);//执行启动事务



        return true;
    }

而startProcessLocked()跳转的最终方法是startProcess()

 private ProcessStartResult startProcess(String hostingType, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            ...
            final ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});//明确了新开启进程的所有的信息,使用Procee.start()开始zygote的fork进程操作
            }
            checkTime(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }



6,Process.java 开始zygote的孵化之旅
 public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int runtimeFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }


小结:这样,我们就从AMS 交给zygote去孵化新的进程,至于zygote如何fork创建进程,暂不展开讨论,后续新的进程开启走了main(),就是后面的过程了。    

下面就是App正式启动main方法的时候了,这之前的源码看来,跟开车一样,先插钥匙,再打火,下一步就是挂档加油门出发了。

小小总结一下:

1,在Launcher进程触发App的跳转,最终通过Binder进程间机制通知给了ActivityManagerService(AMS)

2,AMS通过Zygote.fork()创建一个新的进程,用来启动App的ActivityThread实例

3,App开启main(),进行一系列App真正启动的操作,留给后面再写了。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:34:46  更:2022-07-17 16:37:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 2:53:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码