ANR源码分析之Service Timeout

 在前面的一篇文章中,分析了Broadcast Timeout的流程,接下来继续分析Service Timeout的流程。Service默认不会运行在子线程中,它也不会运行在一个独立的进程中,它同样执行在UI线程中,因此也不能在Service中执行耗时操作,否则也会产生的ANR。

 Service Timeout整体流程如下图所示:



1.startService(ContextImpl.java)

/*
    * 启动服务
    */
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }


    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);//验证Service的Intent
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());//调用AMS的start方法


            ........
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
 2.startService(ActivityManagerService.java)
 在ActivityManagerService.java类中
 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        ......
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);//调用ActiveServices的startServiceLocked方法
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
3.startServiceLocked(ActiveServices.java)
    在ActiveServices.java类中
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, final int userId)
            throws TransactionTooLargeException {


        final boolean callerFg;
        if (caller != null) {
         final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
         .........
         //调用者不是处于后台线程组中
         callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
       } else {
          callerFg = true;
        }
     .......
        S
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值