解决Service Intent must be explicit 崩溃问题
解决Service Intent must be explicit 崩溃问题
Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.example.wang.ordermanager.OrderService }
今天在写一个app间通信的功能时,出现了些小问题,客户端通过aidl绑定服务端的服务,结果在client端应用启动时出现了崩溃,最初代码是这样写的:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
Intent intent = new Intent("com.example.wang.ordermanager.OrderService");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
错误log如下:
04-15 02:26:19.114 1747-1747/? E/uncaughtException: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wang.client/com.example.wang.client.MainActivity}: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.example.wang.ordermanager.OrderService }
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2444)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.example.wang.ordermanager.OrderService }
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1366)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1465)
at android.app.ContextImpl.bindService(ContextImpl.java:1443)
at android.content.ContextWrapper.bindService(ContextWrapper.java:604)
at com.example.wang.client.MainActivity.onCreate(MainActivity.java:68)
at android.app.Activity.performCreate(Activity.java:6367)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
跟了一下源码,发现在ContextImpl中有如下的判断:
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
...
validateServiceIntent(service);
...
}
private void validateServiceIntent(Intent service) {
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));
}
}
}
由此可见,在Android5.0中增加了对intent的判断,因为intent是通过设置action得到的,因此没有Component对象的实例,也没有包名,故而报错。原因找到,增加了一个设置包名的步骤,而且需要是App的包名,而不是Service类所在包的包名,即可顺利解决,代码如下:
Intent intent = new Intent("com.example.wang.ordermanager.OrderService");
intent.setPackage("com.example.wang.ordermanager");
bindService(intent, conn, Context.BIND_AUTO_CREATE);