绑定无法在Android库中定义的远程服务

时间:2013-11-29 14:49:10

标签: java android android-service aidl

我使用AIDL在Android库项目中定义了一个远程服务。该服务应该只是增加一个int。我尝试从另一个项目绑定到它,一个使用该库的应用程序。应用程序对bindService(...)的调用始终返回false。我做错了什么?

应用程序项目的主要活动:

MainActivity.java

package com.example.serviceusera;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.example.service.IncService;
import com.example.service.IncServiceConnection;

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private IncServiceConnection mConnection;
    private int mCount = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        try {
            mConnection = bindService();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to bind service", e);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConnection);
    }

    private IncServiceConnection bindService() throws RemoteException {
        IncServiceConnection connection = new IncServiceConnection();
        Intent service = new Intent(IncService.class.getName());
        boolean bound = bindService(service, connection, Context.BIND_AUTO_CREATE);
        Log.d(TAG, "bindService() = " + bound);
        if (bound) {
            return connection;
        } else {
            throw new RemoteException("Failed to bind service");
        }
    }

    private void init() {
        // Show the current value of the counter
        final EditText text = (EditText) findViewById(R.id.editText1);
        text.setText(Integer.toString(mCount));

        // Set button to increment counter
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    mCount = mConnection.inc(mCount);
                    text.setText(Integer.toString(mCount));
                } catch (RemoteException e) {
                    Log.e(TAG, "Failed to use service", e);
                }
            }
        });

    }

}

图书馆项目:

IIncService.aidl

package com.example.service;

interface IIncService {
    int inc(in int i);
}

IncService.java

package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class IncService extends Service {

    private final IIncService.Stub mBinder = new IIncService.Stub() {
        @Override
        public int inc(int i) throws RemoteException {
            return i + 1;
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

}

IncServiceConnection.java

package com.example.service;

import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

public class IncServiceConnection implements ServiceConnection {

    private IIncService mService;

    public int inc(int i) throws RemoteException {
        return mService.inc(i);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mService = IIncService.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }

}

我已将该服务添加到库的清单中:

的AndroidManifest.xml

...
<application
        ...
        <service
            android:name="com.example.service.IncService"
            android:process=":remote" >
        </service>
 </application>
...

并在应用程序中启用了mainfest合并:

project.properties

...
manifestmerger.enabled=true

2 个答案:

答案 0 :(得分:2)

我已经使用IntelliJ Idea 13尝试了您的代码并找到了问题。 首先,我确保:

  1. 导出图书馆项目;
  2. 应用程序项目在Android Compiler属性下有Enable manifest merging;
  3. 使用该配置它不起作用,我观察到Unable to start service Intent

    此处的问题是Intent创建不正确。似乎您通过IncService.class.getName()获取的类名称未完全指定组件(如果选中日志,则看起来如此,因为intent仅包含类名,但是包名称丢失)。因此,为了正确指定组件,我使用了另一种方式:

    final Intent service = new Intent(this, IncService.class);
    

    它运作良好。

答案 1 :(得分:0)

尝试使用与Handler绑定,而不是绑定Ibinder。我最近以你的方式做了一个应用程序,我无法弄清楚错误。但与Messager合作使事情变得更容易。 而不是返回binder对象。它返回消息obj。这是参考。

Source: Android Remote Bound Services