当前位置: 首页 > news >正文

源码探探之StartActivity(一)

源码基于API 26

startActivity()上车

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}复制代码

没什么好说的

//启动一个activity不需要返回值
//如果context之外调用startActivity(),需要给intent添加{@link Intent#FLAG_ACTIVITY_NEW_TASK}
//@param options 附加的选项指示如果启动activity
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        //可重写该方法兼容应用需求
        startActivityForResult(intent, -1);
    }
}复制代码

可重写该方法,参考FragmentActivity

//If requestCode >= 0, this code will be returned in onActivityResult() when the activity exits.
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}复制代码

最终执行该方法

//启动一个activity在finish()会返回一个结果在onActivityResult()中
//如果在onCreate()/onResume()方法中调用该方法,window不显示界面直到该方法返回结果
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    //父activity一般为空
    if (mParent == null) {
        //通过ActivityOptions帮助类生成一个bundle,指示该如何启动该activity
        options = transferSpringboardActivityOptions(options);
        //Instrumentation基类启动Activity
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        //返回结果
        if (ar != null) {
            //最终会执行Activity的onActivityResult()
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            //当接收到返回的结果了启动的activity才会显示
            mStartedActivity = true;
        }
        //取消输入并开始activity退出动画
        cancelInputsAndStartExitTransition(options);
    } else {
        //不考虑mParent不为null的情况,远古级方法,不采用了
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}复制代码

执行Instrumentation的execStartActivity(),Instrumentation起着监控系统和应用的作用

//target:源activity
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    //获取当前内容索引,不重写onProvideReferrer()返回null
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        //不为null添加至intent
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    //activity监视器
    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并离开当前进程
        intent.prepareToLeaveProcess(who);
        //本地activityManager启动activity
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        //检查启动activity返回结果,抛出异常
        checkStartActivityResult(result, intent);
        //跨进程异常
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}复制代码

ActivityManagerNative.getDefault()获取IActivityManager接口,调用startActivity()方法。
事实上是ServiceManager.getService("activity"), 即获取ActivityManagerService(AMS)并通过Binder远程调用ActivityManagerService类的startActivity()方法。

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        //获取activityService
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        //返回service代理对象
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};
static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    //通过binder获取AMS
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    //代理obj其实就是AMS
    return new ActivityManagerProxy(obj);
}复制代码

IAvityManager对所有运行着的Activity交互提供了接口,ActivityMangerNative实现了IActivityManager接口,IActivityManger的大多数功能都是调用了ActivityManagerNative类接口来完成的,而AMS继承了ActivityMangerNative。
ActivityMangerNative作为IActivityManger和AMS的中间类,解耦了两者间的依赖,所有对AMS的访问都转换成了对ActivityMangerNative的代理类ActivityMangerProxy的访问。

从这里的getDefault().startActivity()开始从本应用通过binder跨进程调用AMS的方法

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            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 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);
}复制代码

ActivityStarter类负责处理启动activity之前的准备工作,包括Activity的Intent和Flags的逻辑, 还有管理Stack和TaskRecord.
ActivityStarter类的调用流程:

  • ActivityStarter#startActivityMayWait(根据Intent获取Activity的启动信息(ResolveInfo和ActivityInfo)
  • ActivityStarter#startActivityLocked(创建ActivityRecord, 含有Activity的核心信息)
  • ActivityStarter#startActivityUnchecked(根据启动的Flag信息, 设置TaskRecord)

接着执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked()方法

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    }
    return false;
}复制代码

ActivityStackSupervisor类与ActivityStack类配合使用. ActivityStackSupervisor负责管理Task和Stack, 而ActivityStack负责管理在Stack和Task中的Activity

ActivityStackSupervisor类与ActivityStack类的调用流程:

  • ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
  • ActivityStack#resumeTopActivityUncheckedLocked
  • ActivityStack#resumeTopActivityInnerLocked(根据ActivityRecord和ActivityOptions完成Activity的切换, 移至栈顶)
  • ActivityStackSupervisor#startSpecificActivityLocked
  • ActivityStackSupervisor#realStartActivityLocked(真正启动activity)

     final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
             boolean andResume, boolean checkConfig) throws RemoteException {
         ...
         app.forceProcessStateUpTo(mService.mTopProcessState);
         app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                 System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                 new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                 task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                 newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
         ...
     }复制代码

    最后由ActivityThread中的ApplicationThread调用scheduleLaunchActivity完成Activity的真正启动。
    这里的thread是IApplicationThread接口,该接口继承了IInterface接口,实现方法asBinder()方法作为binder通信。

    这里通过binder跨进程由系统进程调用应用进程启动activity

相关文章:

  • 《见与不见》
  • 旅行(LCA)
  • Linux正则表达式元字符
  • AMD首款APU的价值和机会
  • BMap:JavaScript API
  • Java注释讲解
  • Android前景,前途(转)
  • GPU的线程模型和内存模型
  • 深入浅出ShellExecute
  • 概率校准Probability Calibration
  • PHP漏洞全解(九)-文件上传漏洞
  • 1531 山峰 【栈的应用】
  • Activity 5秒 Broadcast 10秒 Service 20秒
  • Windows 8 C#调用C++编写的Windows运行时组件
  • SQL Server 索引基础知识(1)--- 记录数据的基本格式
  • [nginx文档翻译系列] 控制nginx
  • __proto__ 和 prototype的关系
  • Angular2开发踩坑系列-生产环境编译
  • CODING 缺陷管理功能正式开始公测
  • Java程序员幽默爆笑锦集
  • Python - 闭包Closure
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 初识 webpack
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 聊聊flink的TableFactory
  • 嵌入式文件系统
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • MyCAT水平分库
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (10)STL算法之搜索(二) 二分查找
  • (接口自动化)Python3操作MySQL数据库
  • (十五)使用Nexus创建Maven私服
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)u-boot-nand.bin的下载
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理(一):@echo off
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .Net Web项目创建比较不错的参考文章
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET开发不可不知、不可不用的辅助类(一)
  • .NET企业级应用架构设计系列之技术选型
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • @media screen 针对不同移动设备
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [2013AAA]On a fractional nonlinear hyperbolic equation arising from relative theory
  • [20171113]修改表结构删除列相关问题4.txt
  • [30期] 我的学习方法
  • [Android] 修改设备访问权限
  • [Android]如何调试Native memory crash issue
  • [Angular 基础] - 自定义指令,深入学习 directive
  • [bzoj1901]: Zju2112 Dynamic Rankings