Android IPC,服务未实例化

Android IPC, Service Not Getting Instantiated

我有一个服务驻留在像这样的 lib 项目中

public abstract class MyService extends Service{
    //service body here 
}

我已将 aidl 文件设置为与远程服务进行通信,该服务也包含在此处复制 aidl 文件的 lib 项目中

package mypackage;

// Declare the communication interface which holds all of our exposed functions.
interface IMyService {
    //interface body here 
}

在 lib 清单中,我已经声明了这样的服务

<service
    android:name="mypackage.core.MyService"
    android:enabled="true"
    android:exported="true"
    android:process=":remote" >

    <intent-filter>
        <action android:name="mypackage.IMyService" />
    </intent-filter>

</service>

我已将此库包含在我的应用程序中,但是当我尝试从应用程序绑定服务时,它没有被实例化。任何人都可以建议我做错了什么,如果可以的话,可以指导我出路。中的服务正在另一个 class 中启动,它属于这样的库

try{
    Intent i = new Intent(MyService.class.getName());
    i.setPackage("mypackage");
    // start the service explicitly.
    // otherwise it will only run while the IPC connection is up.       
    mAppContext.startService(i);
    boolean ret = mAppContext.bindService(i,
            mConnection, Service.BIND_AUTO_CREATE);
    if(!ret){
        MyLogger.log("Error");
    }
}catch(Exception e){
    MyLogger.log("err");
}

服务绑定 API 总是 returns false 会是什么问题。这是创建 RemoteService 的主要方式吗?如果需要,我是否需要在应用程序清单中添加此服务?

what would be the issue

首先,您的 Intent 与您的 <service> 不匹配。

Intent i = new Intent(MyService.class.getName());

您正在传递看起来类似于 mypackage.core.MyService 的操作 String。但是,这不是 <action>Service:

<action android:name="mypackage.IMyService" />

因此,您的 Intent 没有匹配任何内容,您无法绑定。


其次,您的Service非常不安全。任何想要绑定的应用程序都可以绑定到它。如果您希望其他应用程序绑定到它,那很好,但是使用一些权限保护它,这样用户就可以投票决定哪些应用程序可以绑定到它。


第三,您正在使用隐式 Intent 进行绑定,它使用诸如操作字符串之类的东西。这在 Android 5.0+ 上不起作用,因为您不能再使用隐式 Intent 绑定到服务。使用隐式 Intent 来发现服务很好,但是您随后需要将 Intent 转换为包含组件名称的显式服务。这是我在 this sample app:

中执行此操作的方法
  @Override
  public void onAttach(Activity host) {
    super.onAttach(host);

    appContext=(Application)host.getApplicationContext();

    Intent implicit=new Intent(IDownload.class.getName());
    List<ResolveInfo> matches=host.getPackageManager()
                                  .queryIntentServices(implicit, 0);

    if (matches.size()==0) {
      Toast.makeText(host, "Cannot find a matching service!",
                      Toast.LENGTH_LONG).show();
    }
    else if (matches.size()>1) {
      Toast.makeText(host, "Found multiple matching services!",
                      Toast.LENGTH_LONG).show();
    }
    else {
      Intent explicit=new Intent(implicit);
      ServiceInfo svcInfo=matches.get(0).serviceInfo;
      ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName,
                                         svcInfo.name);

      explicit.setComponent(cn);
      appContext.bindService(explicit, this, Context.BIND_AUTO_CREATE);
    }
  }

Is this the prominent way of creating a RemoteService ?

很少有人创建远程服务。它们难以保护,难以处理协议中的版本更改等。而且,在你的情况下,我不知道你为什么认为你需要远程服务,因为你显然是从你自己的应用程序绑定到服务。