美文网首页Android技术知识
Activity的启动过程第一篇

Activity的启动过程第一篇

作者: b496178cdc84 | 来源:发表于2016-09-06 09:45 被阅读93次

    最近研究动态加载,发现,要想做的好,涉及的面太广了,从classloader 到 android应用程序框架,都要有深刻的了解,所以开 始学习并记录一些知识。希望对大家有所帮助。以下信息基本来自网络或者,老罗的Android系统源代码情景分析。

    一般,Aty的启动,包含三个部分,第一个是Laucher , 第二个MainAty(程序的入口Aty),第三个是AMS(AndroidManagerService),他们三个的关系,总结起来一句话就是, Laucher通过AMS 来启动MainAty, 而且 他们三个不在同一个进程中,是靠binder进行通信的

    一、先来说Aty的启动过程

    1、Laucher组件 首先向AMS(AndroidManagerService)发送一个启动Mainactivity的请求, 这个请求是进程间通信的。
    2、AMS首先将要启动的MainActivity组件的信息保留起来,然后向Laucher组件发送一个进入终止状态的进程通信。
    3、然后,Laucher组件会接收到AMS发来的中止请求,进入中止状态, 然后再向AMS发送消息,告诉AMS 我已经进入中止状态了,你请继续做你的是事情,这样AMS就能继续进行启动Aty的操作。
    4、由于MainAty的启动是在Lauther程序中启动的,Lauther中止了,程序应用进程也就不存在了,然后AMS就会新启动一个应用进程。
    5、新的应用进程启动后,就会告诉AMS 我(新的应用进程)已经启动好了,然后发一个通信请求给AMS。
    6、接收到新应用进程发来的通信后,AMS就会把第二步保留的组件信息 传递给新的进程,然后新的进程就可以靠这些信息去启动MainAty。

    Step1 看源码

    //在Launcher里面
    void startActivityForResultSafely(Intent intent, int requestCode) {
       boolean startActivitySafely(View v, Intent intent, Object tag) {
            boolean success = false;
            try {
                //会调用这个方法
                success = startActivity(v, intent, tag);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
            }
            return success;
        }
    
        }
    
    
     boolean startActivity(View v, Intent intent, Object tag) {
            //会把每一个启动的Aty 都放到一个新的任务栈中去启动
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            try {
                // Only launch using the new animation if the shortcut has not opted out (this is a
                // private contract between launcher and may be ignored in the future).
                boolean useLaunchAnimation = (v != null) &&
                        !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
                if (useLaunchAnimation) {
                    ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                            v.getMeasuredWidth(), v.getMeasuredHeight());
                    startActivity(intent, opts.toBundle());
                } else {
                    startActivity(intent);
                }
                return true;
            } catch (SecurityException e) {
                Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                        ". Make sure to create a MAIN intent-filter for the corresponding activity " +
                        "or use the exported attribute for this activity. "
                        + "tag="+ tag + " intent=" + intent, e);
            }
            return false;
        }
    

    这个intent里面的信息 就是例如
    action = "...intent.action.main"
    cataegory = '''.....categroy.laucher'
    cmp = "com.suwanroy.Mainactivity"
    这些不用说估计大家已经很熟悉了。

    OK 那么这个信息是从哪里来的呢 Lauther是从哪里获取这些东西的?

    系统在启动的时候,会先启动PMS(PackageManagerService),PMS是用来安装APP的,PMS在安装APP之前,会先解析APP的mainfest文件,得到APP里面的组件信息,然后会启动Launcher,Launcher会在PMS中寻找所有Action为Intent.ActionMain Category为 Intent.CATEGORY_LAUNCHER的组件,然后为他们每一个生成一个APP图标,然后把图标和他们的信息关联起来,用户点击图标就会启动相应的MainAty。

    Step2 现在到Activitty
    在Launcher 里面调用最终都会调用到Activity类中的startactivityforresult方法。看源码

        @Override
        public void startActivity(Intent intent, Bundle options) {
           //可以看到,resultCode都为-1,所以,这个launcher 不会知道MainAty启动后的东西
            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);
            }
        }
        //OK,最终走到了这个方法。
        public void startActivityForResult(Intent intent, int requestCode, 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) {
                    // 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;
                }
    
                final View decor = mWindow != null ? mWindow.peekDecorView() : null;
                if (decor != null) {
                    decor.cancelPendingInputEvents();
                }
                // 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);
                }
            }
        }
    

    文章不发太长,发太长不利于消化。下一篇,将分析这里面的代码,有书里面的,也有一些自己看源码后的见解,大家喜欢的话可以关注我,以后会主要发一些动态加载,和Android自动化测试的一些东西。大家一起成长,一起进步

    相关文章

      网友评论

        本文标题:Activity的启动过程第一篇

        本文链接:https://www.haomeiwen.com/subject/tzgnsttx.html