当手动杀死contentprovider依赖的宿主service进程时,进程在被重新创建时报错
04-23 11:32:59.605 14977-14977/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gxott.plugin, PID: 14977
java.lang.SecurityException: Unable to find app for caller android.app.ApplicationThreadProxy@2ccd9888 (pid=14977) when publishing content providers
at android.os.Parcel.readException(Parcel.java:1472)
at android.os.Parcel.readException(Parcel.java:1426)
at android.app.ActivityManagerProxy.publishContentProviders(ActivityManagerNative.java:2886)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4407)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4338)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5030)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:649)
at dalvik.system.NativeStart.main(Native Method)
04-23 11:32:59.608 14977-14977/? I/Process: Sending signal. PID: 14977 SIG: 9
下面是查看源码显示
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}
enforceNotIsolatedCaller("publishContentProviders");
synchronized (this) {
final ProcessRecord r = getRecordForAppLocked(caller);
if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
if (r == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when publishing content providers");
}
final long origId = Binder.clearCallingIdentity();
final int N = providers.size();
for (int i = 0; i < N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
}
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
dst.notifyAll();
}
updateOomAdjLocked(r);
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
}
Binder.restoreCallingIdentity(origId);
}
}
主要是service启动是aidl绑定启动的,当手动杀死service,重启service时由于service里有contentprovider的信息,会调用publishContentProviders,在进行binder判断时,由于获取的绑定客户端进程为空导致报错。
解决方案有以下:
1.去掉contentprovider
2.第三方客户端进程重新绑定service进程
对于这种错误,如果service只提供aidl接口是不用管这个错误的,当重新绑定时,service进程会重新创建。