Open zengjingfang opened 6 years ago
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
// 可以观察到异常是在此处抛出
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}
public final void appendFrom(Parcel parcel, int offset, int length) {
// 由于 parcel.mNativePtr中 parcel为null,所以抛出了NullPointerException
nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
}
根据上述的源码追踪分析,极有可能是在bindservice的时候进程意外死亡或者进行binder通信时内存被回收等情况,导致了这个parcel为null,抛出了异常。处理就是在APP业务代码中bindservice操作时进行一次“try catch”,保证程序不崩溃。如果出现该情况,也就意味着bindService失败,是否要进一步处理根据环境而定。
经过验证上述方式是无法解决问题的,真正的原因是在startService(intent)中的intent,使用了putExtra传输数据,但是所传的key偏长,或者说数据过大,导致系统底层出现了异常,抛出了NullPointerException,最终导致RuntimeException,所以真正的解决办法是在bindservice动作的intent里面不通过putExtra传输参数。经过版本验证修改了没有出现该异常。