Android bindService()在使用AIDL时返回false?

时间:2014-07-12 02:27:48

标签: java android

由于某种原因,我无法绑定到我的服务?我需要运行onServiceConnected()方法,以便我可以使用我的AIDL接口。我做错了什么?

private ServiceConnection serviceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        Log.d("BindingService", "Service trying to bind!");
        sendService = ISendMessageService.Stub.asInterface((IBinder) service);
        boundToService = true;
        pendingFragment.bindToService();
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        sendService = null;
        boundToService = false;
        pendingFragment.unbindService();
    }
};

主要活动方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    schedulerFragment = new SchedulerFragment();
    pendingFragment = new PendingFragment();

    fm = getFragmentManager();

    titleBar = getActionBar();
    titleBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    scheduleTab = titleBar.newTab();
    pendingTab = titleBar.newTab();

    scheduleTab.setText("Schedule");
    pendingTab.setText("Pending");

    scheduleTab.setTabListener(new MyTabListener(schedulerFragment));
    pendingTab.setTabListener(new MyTabListener(pendingFragment));

    titleBar.addTab(scheduleTab);
    titleBar.addTab(pendingTab);

    titleBar.selectTab(scheduleTab);

    Boolean success = getApplicationContext().bindService(new Intent(SendMessageService.class.getName()),
            serviceConnection, Context.BIND_AUTO_CREATE);
    Log.d("ServiceConnection", success.toString());
}
@Override
public void onStop() {
    super.onStop();
    if (boundToService) {
        unbindService(serviceConnection);
    }
}

@Override
public void onPause() {
    super.onPause();
    if (boundToService) {
        unbindService(serviceConnection);
    }
}

这是服务的onBind()函数:

@Override
public IBinder onBind(Intent intent) {
    mBinder =  new ISendMessageService.Stub(){

        @Override
        public void deleteMessage(int index) throws RemoteException {
            TimedMessage m = schedule.get(index);
            schedule.get(index).alarm.cancel(m.intent);
            schedule.remove(m);
        }

        @Override
        public void cancelAllMessages() throws RemoteException {
            for(TimedMessage m : schedule){
                m.alarm.cancel(m.intent);
            }
            schedule.clear();
        }

    };
    return mBinder;

清单:

<service
        android:name="com.pearhill.messagesender.SendMessageService"
        android:enabled="true"
        android:exported="true"
        android:process=":remote" >
        <intent-filter>
            <action android:name="com.pearhill.messagesender.ISendMessageService.aidl" />
        </intent-filter>
    </service>

1 个答案:

答案 0 :(得分:0)

以下是完整说明的链接:

https://developer.android.com/guide/components/bound-services.html

https://developer.android.com/guide/components/aidl.html#Calling

  1. 作为关键点,请确保将您的援助物品正确复制到您的应用程序中。清理项目并删除aidl。
  2. 然后将aidl复制到aidl文件夹中的应用程序,但包名称与remote aidl相同。重建。你不必在androidManifest中调用应用程序提供服务;它将由你复制的aidl接口处理。
  3. 确保服务也是应用程序,而不是库(jar类型)。至少我们无法使用jar文件中的服务。您可以选择&#34;没有活动&#34;如果您不打算创建本地活动,请在新的应用程序向导中。在这种情况下,您可以使用&#34; Build-&gt; Build Apk&#34;创建apk。 Android studio中的菜单,用于基于服务的应用。确保在从远程应用程序运行BindService之前安装服务apk。您不需要运行服务,因为BindService也会启动该服务,但您需要安装apk,以便它在系统中可用。您可以使用adb install path / myapkname.apk。
  4. 动作名称不是必须的,但这就是我们绑定服务的方式,其中&#34; com.example.RemoteService.BIND&#34;是服务的行动名称:

    String pkg = IRemoteService.class.getPackage().getName();
                //get the class name from the interface package
                String interfaceName = IRemoteService.class.getName();
                String clsName = interfaceName.replace("IRemoteService", "RemoteService");
    Intent it = new Intent("com.example.RemoteService.BIND");
                    it.setClassName(pkg, clsName);
                    boolean bRet = getApplicationContext().bindService(it, mConnection, Service.BIND_AUTO_CREATE);
                    Log.d("IRemote", "IRemoteService Service.BIND_AUTO_CREATE return: " + bRet);
    

    这是eclipse中使用的工作,但由于明确的意图,在Android工作室中失败了:

        Intent it = new Intent( );
        it.setClassName("com.example.aidlservice",
         "com.example.aidlservice.MyService");
        //optional
        it.setAction("com.example.RemoteService.BIND");
        //binding to remote service
        boolean bRet = bindService(it, mServiceConnection, Service.BIND_AUTO_CREATE);
        Log.d("IRemote", "Service.BIND_AUTO_CREATE");
    
  5. 这是服务应用程序的清单。出于安全原因,您可能需要添加权限:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.testaidl">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    
            <service android:name=".RemoteService" android:process=":remote" android:exported="true">
                <intent-filter>
                    <action android:name="com.example.RemoteService.BIND" />
                </intent-filter>
            </service>
        </application>
    
    </manifest>