Android深入四大组件(四)广播的注册、发送和接收过程

相关文章

Android深入理解四大组件系列

前言

我们接着来学习Android四大组件中的BroadcastReceiver,广播主要就是分为注册、接收和发送过程。建议阅读此文前请先阅读Android深入理解四大组件系列的文章,知识重复的部分,本文不再赘述。

1.广播的注册过程

BroadcastReceiver的注册分为两种,分别是静态注册和动态注册,静态注册在应用安装时由PackageManagerService来完成注册过程,关于这一过程,我会在后续的介绍PackageManagerService文章中详细介绍。这里只介绍BroadcastReceiver的动态注册。

要想动态注册BroadcastReceiver,需要调用registerReceiver方法,它的实现在ContextWrapper中,代码如下所示。

frameworks/base/core/java/android/content/ContextWrapper.java

Override
public Intent registerReceiver(
    BroadcastReceiver receiver, IntentFilter filter) {
    return mBase.registerReceiver(receiver, filter);
}

这里mBase具体指向就是ContextImpl,不明白的请查看Android深入四大组件(二)Service的启动过程这篇文章。ContextImpl的registerReceiver方法有很多重载的方法最终会调用registerReceiverInternal方法:

frameworks/base/core/java/android/app/ContextImpl.java

  private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context) {
        IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {//1
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);//2
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();//3
            }
        }
        try {
            final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);//4
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess();
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

在注释1处判断如果LoadedApk类型的mPackageInfo不等于null并且context不等null就调用注释2处的代码通过mPackageInfo的getReceiverDispatcher方法获取rd对象,否则就调用注释3处的代码来创建rd对象。注释2和3的代码的目的都是要获取IIntentReceiver类型的rd对象,IIntentReceiver是一个Binder接口,用于进行跨进程的通信,它的具体实现在

LoadedApk.ReceiverDispatcher.InnerReceiver,如下所示。

frameworks/base/core/java/android/app/LoadedApk.java

  static final class ReceiverDispatcher {
        final static class InnerReceiver extends IIntentReceiver.Stub {
            final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
            final LoadedApk.ReceiverDispatcher mStrongRef;
            InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
                mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
                mStrongRef = strong ? rd : null;
            }
          ...
         }
        ...
   }

回到registerReceiverInternal方法,在注释4处调用了ActivityManagerProxy(AMP)的registerReceiver方法,最终会调用AMS的registerReceiver方法,并将rd传就去。不明白的同学请查看Android深入四大组件(一)应用程序启动过程(前篇),这里不再赘述。

查看AMS的registerReceiver方法,如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
...
 synchronized(this) {
  ...
            Iterator<String> actions = filter.actionsIterator();//1
  ...
            // Collect stickies of users
            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
            while (actions.hasNext()) {
                String action = actions.next();
                for (int id : userIds) {
                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
                    if (stickies != null) {
                        ArrayList<Intent> intents = stickies.get(action);
                        if (intents != null) {
                            if (stickyIntents == null) {
                                stickyIntents = new ArrayList<Intent>();
                            }
                            stickyIntents.addAll(intents);//2
                        }
                    }
                }
            }
        }
  ArrayList<Intent> allSticky = null;
        if (stickyIntents != null) {
            final ContentResolver resolver = mContext.getContentResolver();
            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
                Intent intent = stickyIntents.get(i);
                if (filter.match(resolver, intent, true, TAG) >= 0) {
                    if (allSticky == null) {
                        allSticky = new ArrayList<Intent>();
                    }
                    allSticky.add(intent);//3
                }
            }
        }
 ...
}

注释1处根据传入的IntentFilter类型的filter的得到actions列表,根据actions列表和userIds(userIds可以理解为应用程序的uid)得到所有的粘性广播的intent,并在注释2处传入到stickyIntents中,在注释3处将这些粘性广播的intent存入到allSticky列表中,从这里可以看出粘性广播是存储在AMS中的。

接着查看AMS的registerReceiver方法的剩余内容:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
...
        synchronized (this) {
          ...
            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());//1
            if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);//2
                if (rl.app != null) {
                    rl.app.receivers.add(rl);
                }
                ...
            }
            ...
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId);//3
            rl.add(bf);//4
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
            }
            mReceiverResolver.addFilter(bf);//5
            ...
            return sticky;
        }
}

注释1处获取ReceiverList列表,如果为空则在注释2处创建,ReceiverList继承自ArrayList,用来存储广播接收者。在注释3处创建BroadcastFilter并传入此前创建的ReceiverList,BroadcastFilter用来描述注册的广播接收者,并在注释4通过add方法将自身添加到ReceiverList中。注释5处将BroadcastFilter添加到mReceiverResolver中,这样当AMS接收到广播时就可以从mReceiverResolver中找到对应的广播接收者了。下面给出广播的注册过程的时序图。

2.广播的发送和接收过程

ContextImpl到AMS的调用过程

广播可以发送多种类型,包括无序广播(普通广播)、有序广播和粘性广播,这里以无序广播为例,来讲解广播的发送过程。

要发送无序广播需要调用sendBroadcast方法,它的实现同样在ContextWrapper中:

frameworks/base/core/java/android/content/ContextWrapper.java

  @Override
    public void sendBroadcast(Intent intent) {
        mBase.sendBroadcast(intent);
    }

接着来看ContextImpl中的sendBroadcast方法,如下所示。

frameworks/base/core/java/android/app/ContextImpl.java

  @Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            ActivityManagerNative.getDefault().broadcastIntent(
                    mMainThread.getApplicationThread(), intent, resolvedType, null,
                    Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                    getUserId());//1
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

注释1处又是熟悉的代码,最终会调用AMS的broadcastIntent方法:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

  public final int broadcastIntent(IApplicationThread caller,
            Intent intent, String resolvedType, IIntentReceiver resultTo,
            int resultCode, String resultData, Bundle resultExtras,
            String[] requiredPermissions, int appOp, Bundle bOptions,
            boolean serialized, boolean sticky, int userId) {
        enforceNotIsolatedCaller("broadcastIntent");
        synchronized(this) {
            intent = verifyBroadcastLocked(intent);//1
          ...
            /**
            * 2
            */
            int res = broadcastIntentLocked(callerApp,
                    callerApp != null ? callerApp.info.packageName : null,
                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                    requiredPermissions, appOp, bOptions, serialized, sticky,
                    callingPid, callingUid, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

我们来查看注释1处的verifyBroadcastLocked方法:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 final Intent verifyBroadcastLocked(Intent intent) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors() == true) {//1
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        int flags = intent.getFlags();//2
        if (!mProcessesReady) {
            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {//3
            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {//4
                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
                        + " before boot completion");
                throw new IllegalStateException("Cannot broadcast before boot completed");
            }
        }
        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
            throw new IllegalArgumentException(
                    "Can‘t use FLAG_RECEIVER_BOOT_UPGRADE here");
        }
        return intent;
    }

verifyBroadcastLocked方法主要是验证广播是否合法,在注释1处验证intent是否不为null并且有文件描述符。注释2处获得intent中的flag。注释3处如果系统正在启动过程中,判断如果flag设置为FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT(启动检查时只接受动态注册的广播接收者)则不做处理,如果不是则在注释4处判断如果flag没有设置为FLAG_RECEIVER_REGISTERED_ONLY(只接受动态注册的广播接收者)则会抛出异常。

我们再回到broadcastIntent方法,在注释2处调用了broadcastIntentLocked方法,代码如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
  ...
       if ((receivers != null && receivers.size() > 0)
                || resultTo != null) {
            BroadcastQueue queue = broadcastQueueForIntent(intent);
            /**
            * 1
            */
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                    callerPackage, callingPid, callingUid, resolvedType,
                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                    resultData, resultExtras, ordered, sticky, false, userId);
     ...               

            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
            if (!replaced) {
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();//2
            }
        }
        ...
        }
        return ActivityManager.BROADCAST_SUCCESS;
}

这里省略了很多代码,前面的工作主要是将动态注册的广播接收者和静态注册的广播接收者按照优先级高低存储在不同的列表中,再将这两个列表合并到receivers列表中,这样receivers列表包含了所有的广播接收者(无序广播和有序广播)。在注释1处创建BroadcastRecord对象并将receivers传进去,在注释2处调用BroadcastQueue的scheduleBroadcastsLocked方法。

这里先给出ContextImpl到AMS的调用过程的时序图。

AMS到BroadcastReceiver的调用过程

BroadcastQueue的scheduleBroadcastsLocked方法的代码如下所示。

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

public void scheduleBroadcastsLocked() {
...
    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));//1
    mBroadcastsScheduled = true;
}

在注释1处向BroadcastHandler类型的mHandler对象发送了BROADCAST_INTENT_MSG类型的消息,这个消息在BroadcastHandler的handleMessage方法中进行处理,如下所示。

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

private final class BroadcastHandler extends Handler {
    public BroadcastHandler(Looper looper) {
        super(looper, null, true);
    }
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BROADCAST_INTENT_MSG: {
                if (DEBUG_BROADCAST) Slog.v(
                        TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
                processNextBroadcast(true);
            } break;
       ...
        }
    }
}

在handleMessage方法中调用了processNextBroadcast方法,processNextBroadcast方法对无序广播和有序广播分别进行处理,旨在将广播发送给广播接收者,下面给出processNextBroadcast方法中对无序广播的处理部分。

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

  final void processNextBroadcast(boolean fromMsg) {
  ...
            if (fromMsg) {
                mBroadcastsScheduled = false;//1
            }
            // First, deliver any non-serialized broadcasts right away.
            while (mParallelBroadcasts.size() > 0) {//2
                r = mParallelBroadcasts.remove(0);//3
               ...
                for (int i=0; i<N; i++) {
                  Object target = r.receivers.get(i);
                  if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                            "Delivering non-ordered on [" + mQueueName + "] to registered "
                            + target + ": " + r);
                  deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);//4
                }
           ...
            }
  }

从前面的代码我们得知fromMsg的值为true,因此注释1处会将mBroadcastsScheduled 设置为flase,表示对于此前发来的BROADCAST_INTENT_MSG类型的消息已经处理了。注释2处的mParallelBroadcasts列表用来存储无序广播,通过while循环将mParallelBroadcasts列表中的无序广播发送给对应的广播接收者。在注释3处获取每一个mParallelBroadcasts列表中存储的BroadcastRecord类型的r对象。注释4处将这些r对象描述的广播发送给对应的广播接收者,deliverToRegisteredReceiverLocked方法如下所示。

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
        BroadcastFilter filter, boolean ordered, int index) {
...
   try {
            if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
                    "Delivering to " + filter + " : " + r);
            if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
             ...
            } else {
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId);//1
            }
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
            }
        } catch (RemoteException e) {
 ...
        }

}

这里省去了大部分的代码,这些代码是用来检查广播发送者和广播接收者的权限。如果通过了权限的检查,则会调用注释1处的performReceiveLocked方法:

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

  void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
        // Send the intent to the receiver asynchronously using one-way binder calls.
        if (app != null) {//1
            if (app.thread != null) {//2
                // If we have an app thread, do the call through that so it is
                // correctly ordered with other one-way calls.
                try {
                    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser, app.repProcState);//3
                }
            }
            ...
        } else {
            receiver.performReceive(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);/
        }
    }

注释1和2处的代码表示如果广播接收者所在的应用程序进程存在并且正在运行,则执行注释3处的代码,表示用广播接收者所在的应用程序进程来接收广播,这里app.thread指的是ApplicationThread,我们来查看ApplicationThread的scheduleRegisteredReceiver方法,代码如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

   public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
            int resultCode, String dataStr, Bundle extras, boolean ordered,
            boolean sticky, int sendingUser, int processState) throws RemoteException {
        updateProcessState(processState, false);
        receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                sticky, sendingUser);//1
    }

注释1处调用了IIntentReceiver类型的对象receiver的performReceive方法,这里实现receiver的类为LoadedApk.ReceiverDispatcher.InnerReceiver,代码如下所示。

frameworks/base/core/java/android/app/LoadedApk.java

  static final class ReceiverDispatcher {
        final static class InnerReceiver extends IIntentReceiver.Stub {
        ...
            InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
                mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
                mStrongRef = strong ? rd : null;
            }
            @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                final LoadedApk.ReceiverDispatcher rd;
                ...
                if (rd != null) {
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);//1
                } else {
             ...
            }
...
}

在注释1处调用了ReceiverDispatcher类型的rd对象的performReceive方法:

frameworks/base/core/java/android/app/LoadedApk.java

  public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
            final Args args = new Args(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);//1
            ...
            if (intent == null || !mActivityThread.post(args)) {//2
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManagerNative.getDefault();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                }
            }
        }

在注释1处将广播的intent等信息封装为Args对象,并在注释2处调用mActivityThread的post方法并传入了Args对象。这个mActivityThread是一个Handler对象,具体指向的就是H,注释2处的代码就是将Args对象通过H发送到主线程的消息队列中。Args继承自Runnable,这个消息最终会在Args的run方法执行,Args的run方法如下所示。

frameworks/base/core/java/android/app/LoadedApk.java

   public void run() {
     ...
        try {
            ClassLoader cl =  mReceiver.getClass().getClassLoader();
            intent.setExtrasClassLoader(cl);
            intent.prepareToEnterProcess();
            setExtrasClassLoader(cl);
            receiver.setPendingResult(this);
            receiver.onReceive(mContext, intent);//1
        } catch (Exception e) {
           ...
        }
       ...
    }

在注释1处执行了广播接收者的onReceive方法,这样注册的广播接收者就收到了广播并得到了intent。

广播的注册、发送和接收过程就讲到这,最后给出剩余部分的调用时序图。



欢迎关注我的微信公众号,第一时间获得博客更新提醒,以及更多成体系的Android相关原创技术干货。

扫一扫下方二维码或者长按识别二维码,即可关注。

时间: 2024-09-29 17:16:22

Android深入四大组件(四)广播的注册、发送和接收过程的相关文章

Android深入四大组件(五)Content Provider的启动过程

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> Android深入四大组件(五)Content Provider的启动过程 - 刘望舒的专栏 - 博客频道 - CSDN.NET 刘望舒的专栏 欲为大树,莫与草争 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书讯]流畅的Pyth

Android四大组件 之一 广播接收者

四大组件 之一 广播接受者    BroadcasetRecevice Android中信息传递的机制: 广播:单向 ,群发 创建要素: 1.声明一个继承BroadcasetRecevice 2.在清单文件中声明 包名.类名 要接收广播的话: 要注册广播接受者的过滤条件: 注册广播接受者有两种形式: 第一种:  在清单文件中直接注册: 例子: 接收短信 1.权限问题   接收短信的权限 <uses-permission android:name="android.permission.RE

个帖子学会Android开发四大组件

黑色幽默Lion 方向比努力重要,能力比知识重要,情商比智商重要! 首页 新闻 新随笔 管理 随笔- 43  文章- 0  评论- 12 一个帖子学会Android开发四大组件 注:本文来自"友盟杯",仅在此阅读,学习 这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity详解二.Service详解三.Broadcast Receiver详解四.Content Provider详解外加一个重要组件 intent的详解. 一.Activity详解Activty的

Android开发四大组件概述

这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity具体解释 二.Service具体解释 三.Broadcast Receiver具体解释 四.Content Provider具体解释 外加一个重要组件 intent的具体解释.(主要来自于网络) 1.Activity 一个Activity通常展现为一个可视化的用户界面.比如,一个activity可能展现为一个用户能够选择的菜单项列表或者展现一些图片以及图 片的标题.一个消息服务应用程序可能包括一个显示联系人列表的ac

Android的四大组件

Android的四大组件:Activity.Service.BroadcastReceiver.Content Provider. Content Provider 属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider 主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口 ① Activity是Android应用中负责与用户交互的组件——大致上把它想象成Swing编程中的JFrame控件.不过它与JFrame的区别在于:JFra

Android开发四大组件--Activity详解

Android开发四大组件--Activity详解 - Android开发教程 Android开发的四大组件在开发中应用中是必不可少的,下面就来详解下四大组件之一Activity,总结自网络.Activty的生命周期的也就是它所在进程的生命周期. 一个Activity的启动顺序: onCreate()——>onStart()——>onResume() 当另一个Activity启动时: 第一个Activity onPause()——>第二个Activity onCreate()——>

Android开发四大组件之Service(实例篇)

关于Service的开发详解已经在上一篇:Android开发四大组件之Service(详解篇)讲的很清楚了,本篇主要对Service的开发实例做下讲解. 程序运行效果图: 程序代码: BindService: package com.jph.servicedemo; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /**

Android深入四大组件(三)Service的绑定过程

相关文章 Android深入理解四大组件系列 前言 我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读Android深入四大组件(二)Service的启动过程这篇文章,知识点重叠的部分,本篇文章将不再赘述. 1.ContextImpl到ActivityManageService的调用过程 我们可以用bindService方法来绑定Service,它的实现在ContextWra

Android深入四大组件(二)Service的启动过程

相关文章 Android深入理解四大组件系列 前言 此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程.建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章. 1.ContextImpl到ActivityManageService的调用过程 要启动Service,我们会调用startService方法,它的实现在C