四大组件的工作过程


一、四大组件的运行状态


1、Activity(展示型组件)


Activity的主要作用是展示一个界面并和用户交互,它扮演的是一种前台界面的角色。
(1)需要在AndroidManifest中注册。
(2)需要借助Intent启动。有显示Intent和隐式Intent。隐式Intent指向一个或多个目标Activity组件,当然也可能没有任何一个Activity组件可以处理这个隐式Intent。
(3)对用户而言是可见的。
(4)可以具有特定的启动模式,比如singleTop、singleTask等。
(5)通过Activity的finish方法来结束一个Activity组件的运行。

2、Service(计算型组件)


Service用于在后台执行一系列计算任务。
(1)需要在AndroidManifest中注册。
(2)需要借助Intent启动。
(3)用户无法感知。
(4)两种状态:启动状态和绑定状态。
(5)启动状态:做后台计算,不需要和外界有直接的交互。尽管Service组件用于执行后台计算,但它本身是运行在主线程中的,因此耗时的后台计算仍然需要在单独的线程中去完成。
(6)绑定状态:这个时候Service内部同样可以进行后台计算,但是处于这种状态时外界可以很方便的和Service组件进行通信。IPC啊~
(7)灵活采用stopService和unBindService这两个方法才能完全停止一个Service组件。

3、BroadcastReceiver(消息型组件)


BroadcastReceiver用于在不同的组件乃至不同的应用之间传递消息。
(1)可以在AndroidManifest中静态注册,这种注册方式不需要应用启动就可以收到相应的广播;也可以在代码中动态注册,Context.registerReceiver()和 Context.unRegisterReceiver(),必须要启动应用才能注册并接收广播。
(2)需要借助Intent启动。
(3)用户无法感知。
(4)在实际开发中通过Context的一系列send方法来发送广播,被发送的广播会被系统发送给感兴趣的广播接收者,发送和接收过程的匹配是通过广播接收者的<intent-filter>来描述的。所以呢,BroadcastReceiver组件可以用来实现低耦合的观察者模式,观察者和被观察者之间可以没有任何耦合。
(5)不适合用来执行耗时操作。
(6)BroadcastReceiver组件一般来说不需要停止,它也没有停止的概念。

4、ContentProvider(数据共享型组件)


ContentProvider用于向其他组件乃至其他应用共享数据。
(1)需要在AndroidManifest中注册。
(2)无需借助Intent启动。
(3)用户无法感知。
(4)它的内部需要实现增删查改这四种操作,在它的内部维持着一份数据集合,这个数据集合既可以通过数据库来实现,也可以采用其他任何类型来实现,比如List和Map,ContentProvider对数据集合的具体实现并没有任何要求。
(5)注意点!!!ContentProvider内部的insert、deleted、update和query方法需要处理好线程同步,因为这几个方法是在Binder线程池中被调用的。
(6)ContentProvider无需手动停止。

二、Activity的工作过程


1、启动Activity

    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);

2、Activity的启动过程


(1)startActivity:startActivity方法有好几种重载方式,但是它们最终都会调用startActivityForResult方法。
在Activity.java文件中:
    @Override
    public void startActivity(Intent intent, 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(Intent intent, int requestCode, Bundle options) {
        /*
         * mParent代表的是ActivityGroup,
         * ActivityGroup最开始被用来在一个界面中嵌入多个Activity,
         * 但是其在API13中已经被废弃了,系统推荐采用Fragment来代替ActivityGroup。
         * */
    	if (mParent == null) {
    		/*
    		 * mMainThread.getApplicationThread()这个参数,它的类型是ApplicationThread,
    		 * ApplicationThread是ActivityThread的一个内部类,
    		 * 在后面的分析中可以发现,ApplicationThread和ActivityThread在Activity的启动过程中发挥着很重要的作用。
    		 * */
            Instrumentation.ActivityResult ar =
            		/*
            		 * 所以说Activity的启动过程转移到了Instrumentation中的execStartActivity方法:
            		 * */
                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);
            }
        }
    }
(3)Instrumentation的execStartActivity方法:在Instrumentation.java文件中。
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        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();
            /*
             * 所以启动Activity的真正实现由ActivityManagerNative.getDefault().startActivity方法来完成。
             * 
             * ActivityManagerService继承自ActivityManagerNative,
             * 而ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,
             * 因此ActivityManagerService也是一个Binder,它是IActivityManager的具体实现。
             * 
             * 由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,
             * 因此它的具体实现是ActivityManagerService。
             * 所以说Activity的启动过程又转移到了ActivityManagerService中,
             * 然后再去看ActivityManagerService的startActivity方法。
             * */
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, null, options);
            /*
             * 检查启动Activity的结果:
             * */
            c
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值