Android源码(5) --- Application 启动流程

来源:互联网 发布:facebook 批量操作软件 编辑:程序博客网 时间:2024/06/03 18:43

应用启动流程

每个Application Linux进程中,Android操作系统会启动这个进程当这个Android组件需要执行的时候,当其不在长时间使用或者系统必须回收内存为其他App时,这个进程会被干掉。

  • 回顾:上篇blog中,介绍了Launcher启动流程,最后点击桌面图标启动应用
protected void onListItemClick(ListView l, View v, int position, long id) {        Intent intent = intentForPosition(position);        startActivity(intent);    }
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);        }    }    // 这里 options 为null,继续走satrtActivityForResult();    public void startActivityForResult(Intent intent, int requestCode) {        startActivityForResult(intent, requestCode, null);    }    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {        if (mParent == null) {            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) {                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);            }        }    }
    1. mInstrumentation.execStartActivity() 首先执行的是execStartActivity;
public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode, Bundle options) {        IApplicationThread whoThread = (IApplicationThread) contextThread;        Uri referrer = target != null ? target.onProvideReferrer() : null;        if (referrer != null) {            intent.putExtra(Intent.EXTRA_REFERRER, referrer);        }        if (mActivityMonitors != null) {            synchronized (mSync) {                final int N = mActivityMonitors.size();                for (int i=0; i<N; i++) {                    final ActivityMonitor am = mActivityMonitors.get(i);                    if (am.match(who, null, intent)) {                        am.mHits++;                        if (am.isBlocking()) {                            return requestCode >= 0 ? am.getResult() : null;                        }                        break;                    }                }            }        }        try {            intent.migrateExtraStreamToClipData();            intent.prepareToLeaveProcess();            int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, who.getBasePackageName(), 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;    }
    1. 这里ActivityManagerNative.getDefault().startActivity获取ActivityManagerNative去跳转Activity,ActivityManagerNative集成自Binder,其实就是进程间的通讯咯,而 ActivityManagerService 继承自这里ActivityManagerNative,在进程间通讯时,调用ActivityManagerNative.startActivity() 调用到ActivityManagerService.startActivity(),Native相当于客户端,Service相当于服务器。
  • 所以继续看一下ActivityManagerService的startActivity方法:
@Overridepublic final int startActivity(IApplicationThread caller, String callingPackage,            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, ProfilerInfo profilerInfo, Bundle options) {        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,            resultWho, requestCode, startFlags, profilerInfo, options,            UserHandle.getCallingUserId());    }     @Override    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {        enforceNotIsolatedCaller("startActivity");        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,                false, ALLOW_FULL_ONLY, "startActivity", null);        // TODO: Switch to user app stacks here.        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,                profilerInfo, null, null, options, false, userId, null, null);    }     final 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 config,            Bundle options, boolean ignoreTargetSecurity, int userId,            IActivityContainer iContainer, TaskRecord inTask) {        intent = new Intent(intent);        // Collect information about the target of the Intent.        ActivityInfo aInfo =                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);        ActivityContainer container = (ActivityContainer)iContainer;        synchronized (mService) {            if (container != null && container.mParentActivity != null &&                    container.mParentActivity.state != RESUMED) {                // Cannot start a child activity if the parent is not resumed.                return ActivityManager.START_CANCELED;            }            .......            int res = startActivityLocked(caller, intent, resolvedType, aInfo,                    voiceSession, voiceInteractor, resultTo, resultWho,                    requestCode, callingPid, callingUid, callingPackage,                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,                    componentSpecified, null, container, inTask);            Binder.restoreCallingIdentity(origId);            .......            return res;        }    }
  • 查看调用关系,startActivity() –> startActivityAsUser() –> startActivityMayWait() –> startActivityLocked()

  • 继续追进, startActivityLocked() –>startActivityUncheckedLocked() –> ActivityStack.startActivityLocked() –> ActivityStackSupervisor.resumeTopActivitiesLocked() –> ActivityStack.resumeTopActivityLocked() –> ActivityStack.resumeTopActivityInnerLocked() –> ActivityStackSupervisor.startSpecificActivityLocked() –> AMS.startProcessLocked()

查看startProcessLocked():

...... checkTime(startTime, "startProcess: asking zygote to start proc");            Process.ProcessStartResult startResult = Process.start(entryPoint,                    app.processName, uid, uid, gids, debugFlags, mountExternal,                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,                    app.info.dataDir, entryPointArgs);            checkTime(startTime, "startProcess: returned from zygote!");......
  • 启动了进程Process.start();app.processName则是进程名

总结

  • 启动一个Application 的四大组件时,入股当前进程没有启动,会首先启动当前进程。
  • 每个Application都有其Linux进程和JVM 运行环境,进程间通过Binder进行通讯
  • 流程图
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天猫618长达20天c店怎么办 新开的淘宝店铺没有生意怎么办 淘宝账号登陆限制用不了花呗怎么办 闲鱼买家签收后说是空盒怎么办 在咸鱼卖东西买家恶意退货怎么办 淘宝联系不上买家物流返回怎么办 换了支付宝绑定手机号退款怎么办啊 淘宝评价错了追评评价错了怎么办 淘宝给客户退款后还给差评怎么办 淘宝账号处于下单保护状态怎么办 淘宝卖家物流单号写错了怎么办 有个人给我发直播消息怎么办 网贷申请多了现在秒拒怎么办 顺丰快递寄的瓜果坏了怎么办 淘宝退货快递公司填错了怎么办 不小心把淘宝账号注销了怎么办 腾讯视频会员开通一个月贵怎么办 微交易买美国指数输了四千块怎么办 淘宝地址中包含了违禁词怎么办 微信支付失败但是钱扣了怎么办 支付宝向别人收款交易关闭了怎么办 从淘宝充的晋江币充值异常怎么办 接手转让店铺会员要求退卡怎么办 转转买手机卖家拒绝退款怎么办 淘宝买的东西电话号码留错了怎么办 平板电脑没电关机没保存文件怎么办 恢复出厂设置需要谷歌账号怎么办 华为手机云端里照片删除了怎么办 客户退货卖家一直没收到货怎么办 在淘宝买到假货投诉不管用怎么办 差评不接电话不回旺旺不要钱怎么办 饿了么同行恶意差评怎么办 苹果手机更新后淘宝用不了怎么办 淘宝网快递丢件了买家怎么办 评价后忘了截图五星好评怎么办 在淘宝被骗了好评返现怎么办 苹果4s微信版本过低怎么办 微信版本太低无法登录怎么办 苹果4微信版本低登录不了怎么办 安卓手机微信版本低登录不了怎么办 苹果微信版本低登录不了怎么办