赞
踩
//android-30
void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
mAm.crashApplicationWithType(app.uid, app.getPid(), app.info.packageName, app.userId,
"Context.startForegroundService() did not then call Service.startForeground(): "
+ serviceRecord, false /*force*/,
ForegroundServiceDidNotStartInTimeException.TYPE_ID);
}
看看是谁调用它的,原来在com.android.server.am.ActivityManagerService里
那就接着看看什么时候发出了SERVICE_FOREGROUND_CRASH_MSG事件,于是又来到ActiveServices.bringDownServiceLocked方法里
根据以下这行注释大概意思就是说在 显示前台服务通知之前就关闭前台服务这个操作是不允许的
那么就有可能是我们启动前台服务,然后前台服务还没执行到android.app.Service#startForeground(int, android.app.Notification) 时就又执行了停止服务,因此才出现了这个奔溃
于是我们可以验证下在startForeground调用之后立马执行stopSelf,看看会不会报同样的错
可惜无法复现,再看看产生这个奔溃的手机,全是android 10这个版本
于是对android 10的设备一番尝试后发现无法复现,那么可能产生的问题就是超时了
后期发现如果是这里产生的奔溃,那么异常是ForegroundServiceDidNotStartInTimeException,如下
android.app.ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{...}
android-30 void serviceForegroundTimeout(ServiceRecord r) { ProcessRecord app; synchronized (mAm) { if (!r.fgRequired || r.destroying) { return; } app = r.app; if (app != null && app.isDebugging()) { // The app's being debugged; let it ride return; } if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "Service foreground-required timeout for " + r); } r.fgWaiting = false; stopServiceLocked(r, false); } if (app != null) { mAm.mAnrHelper.appNotResponding(app, "Context.startForegroundService() did not then call Service.startForeground(): " + r); } }
//android-30
public final class ActiveServices {
// How long the startForegroundService() grace period is to get around to
// calling startForeground() before we ANR + stop it.
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
}
//android-30 com.android.server.am.ActiveServices#scheduleServiceForegroundTransitionTimeoutLocked
void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
if (r.app.mServices.numberOfExecutingServices() == 0 || r.app.getThread() == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
msg.obj = r;
r.fgWaiting = true;
mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
}
public class XxxService extends Service {
@Override
public void onCreate() {
super.onCreate();
try {
Thread.sleep(11000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
另外,根据我的实验和网上的资料,这个问题在android10上出现得比较多(另外,小米的推送sdk在android10上也经常产生这个奔溃:android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{96005dd u0 com.xxx.xxx/com.xiaomi.mipush.sdk.PushMessageHandler}),所以很有理由怀疑是android10系统导致,像android11即使模拟超时10秒,也不会产生此奔溃
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。