Android服务之startService源码分析

先看下继承关系:

startService是Context的抽象方法,调用startService时,会先调用到ContextWrapper的startService方法:

@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}


mBase是ContextImpl的实例,ContextWrapper类的startService方法最终通过ContextImpl类的startService方法来实现:

private ContextImpl(ContextImpl container, ActivityThread mainThread,
        LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
        Display display, Configuration overrideConfiguration, int createDisplayWithId) {
    ...
    // mUser和mMainThread是在构造方法里面赋的值
    mUser = user;
    mMainThread = mainThread;
    ...
}

@Override
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    // mUser是UserHandle的实例,UserHandle实现了Parcelable接口
    return startServiceCommon(service, mUser);
}

/**
 * Logs a warning if the system process directly called a method such as
 * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
 * The "AsUser" variants allow us to properly enforce the user's restrictions.
 */
private void warnIfCallingFromSystemProcess() {
    // 如果是系统进程调用startService方法会打印一个log。
    if (Process.myUid() == Process.SYSTEM_UID) {
        Slog.w(TAG, "Calling a method in the system process without a qualified user: "
                + Debug.getCallers(5));
    }
}

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        // 验证intent的有效性
        validateServiceIntent(service);
        // 准备离开应用程序进程,进入ActivityManagerService进程(意味着bundle的数据要在进程间传递)
        service.prepareToLeaveProcess();
        // 调用ActivityManagerProxy类的startService来实现启动服务的操作
        // ActivityManagerProxy是一个Binder对象的远程接口,而这个Binder对象就是ActivityManagerService。
        ComponentName cn = ActivityManagerNative.getDefault().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                        getContentResolver()), getOpPackageName(), user.getIdentifier());
        if (cn != null) {
            // 权限校验失败
            if (cn.getPackageName().equals("!")) {
                throw new SecurityException(
                        "Not allowed to start service " + service
                        + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
                throw new SecurityException(
                        "Unable to start service " + service
                        + ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
}


一个进程对应一个ActivityThread实例,这个进程中所有的Activity对应这一个ActivityThread实例。

在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,它实现了IApplicationThread接口,它的作用是用来辅助ActivityThread执行一些操作。

mMainThread.getApplicationThread()  得到的是当前启动服务进程(调用者)的ApplicationThread对象

service.resolveTypeIfNeeded(getContentResolver())  得到的是intent的MIME数据类型,它是在解析intent时用到的

getOpPackageName()  得到的是调用者的包名

private void validateServiceIntent(Intent service) {
    // 隐式启动判断,5.1之后不允许隐式启动服务
    if (service.getComponent() == null && service.getPackage() == null) {
        if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
            IllegalArgumentException ex = new IllegalArgumentException(
                    "Service Intent must be explicit: " + service);
            throw ex;
        } else {
            Log.w(TAG, "Implicit intents with startService are not safe: " + service
                    + " " + Debug.getCallers(2, 3));
        }
    }
}


ActivityManagerNative类中的getDefault方法通过单例模式创建ActivityManagerProxy代理对象。

实现继承关系:

ActivityManagerNative类:

/**
 * Retrieve the system's default/global activity manager.
 */
static public IActivityManager getDefault() {
    return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        // 服务查询,返回BinderProxy对象
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        // 创建与特定业务相关的代理对象
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};

/**
 * Cast a Binder object into an activity manager interface, generating
 * a proxy if needed.
 */
static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    // 如果之前已经创建过,则直接返回
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

    // 返回一个ActivityManagerProxy对象
    return new ActivityManagerProxy(obj);
}


Singleton.java抽象类是用懒加载实现的,以后可以参考:

/**
 * Singleton helper class for lazily initialization.
 *
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值