Интерфейс AIDL между двумя приложениями - PullRequest
3 голосов
/ 11 января 2011

Я приклеил всю стену к интерфейсу AIDL. У меня есть приложение, которым нужно управлять с помощью стороннего приложения (у меня достаточно контроля над этим, поэтому я могу попросить их внедрить в свою деятельность все, что мне нужно)

Первоначально мое приложение было также действием с интерфейсом и всем, но я изменил его на фоновую службу и для тестирования я создал фиктивное приложение, которое позволяет запускать приложение службы в фоновом режиме.

Теперь мне нужен способ запрашивать вызовы методов у службы (в основном; start, stop, sendData). Я создал файлы .aidl для обоих приложений. В файле aidl реализован только один метод (здесь приведен другой вопрос.)

package foo.testapp;
interface IScript 
{
     String executeScript(String script); 
}

, в то время как другая помощь такая же, за исключением пакета "foo.otherapp". Реализации, которые я нашел в сети, имели одинаковый пакет для обоих файлов aidl, но для меня это вызывает ошибку (думаю, это просто проблема с моей стороны, так как я ненавижу пространства имен и пакеты, поэтому я часто просто называю их плохо, если важно поменяй их, я могу это сделать)

План состоял в том, чтобы использовать этот метод для отправки строки в службу и просто переключать предварительно определенные строки для вызова правильного метода (также можно просто реализовать три различных метода, если это улучшает использование).

В любом случае ... Не удается подключить помощник, появляется ошибка "Невозможно запустить службу"

{act = foo.testapp.IScript}: не найдено

Я бы предположил, что это связано с моим недоразумением, т. Е. или около того)

это реализация в моем тесте активность приложение

private final IScript.Stub mBinder = new IScript.Stub()
{
    @Override
    public String executeScript(String script) throws RemoteException
    {
        // TODO Auto-generated method stub
    }
};
IScript mService = null;
private ServiceConnection mConnection = new ServiceConnection() 
{
     public void onServiceConnected(ComponentName className, IBinder service) 
     {
         mService = IScript.Stub.asInterface(service);
     }
     public void onServiceDisconnected(ComponentName className) 
     {
         mService = null;
     }
 };

Затем в методе OnCreate () я сделаю это:

bindService(new Intent(IScript.class.getName()),
            mConnection, Context.BIND_AUTO_CREATE);

В классе обслуживания у меня это;

@Override
public IBinder onBind(Intent intent) 
{
    // Select the interface to return.  If your service only implements
    // a single interface, you can just return it here without checking
    // the Intent.
    if (IScript.class.getName().equals(intent.getAction())) 
    {
        return mBinder;
    }
    return null;
}

/**
 * The IRemoteInterface is defined through IDL
 */
private final IScript.Stub mBinder = new IScript.Stub() 
{
    @Override
    public String executeScript(String script) throws RemoteException 
    {
        if (script == "test")
        {
            return "foo";
        }
        return "fail";
    }
};

И, наконец, файлы манифеста;

ну, на самом деле, я понятия не имею, нужно ли мне что-то добавлять в файлы манифеста при работе с aidl. В одном примере я видел это;

    <intent-filter>
        <action android:name="foo.otherapp.IScript" />
    </intent-filter>

и

    <intent-filter>
        <action android:name="foo.testapp.IScript" />
    </intent-filter>

Я бы предположил, что ошибки могут быть где угодно. Я пытался настроить это с помощью жевательной резинки и пластырей. Думаю, я просто неправильно понял основную концепцию этого.

В любом случае, любая помощь приветствуется.

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 18 января 2011

Я решил ответить на свой вопрос, поскольку нашел точное решение.

Моя жизнь с Android

Все работало, просто скопировав источник и изменивИмена пакетов и имена функций правильно (при условии, что вы внедряете это в свой собственный проект)

Источник из папки клиента переходит к активности клиента, а serviceimpl переходит к сервису.Мне не нужно было «Сервисное действие», поэтому я пропустил его (и, похоже, оно все равно не вызывалось).

У меня недостаточно репутации для публикации нескольких ссылок, поэтому вы можете получить исходный код в верхней части страницы.

"Обновление: пожалуйста, ознакомьтесь с обновленным примером программыдля Android SDK 1.5. "

1 голос
/ 11 января 2011

Я тоже с этим боролся.Вы правы в своем предположении, что RemoteInterface.aidl должен иметь одинаковое имя пакета как в сервисе, так и в тестовом приложении - так куда вы его поместите!?

Если вы разрабатываете в Eclipse, то хитростьдолжен иметь общую исходную папку (общую для обоих проектов). Сделайте эту папку вне обоих проектов и в свойствах / источнике сборки, нажмите «ссылка на источник» и найдите расположение общего источника.(Вы можете назвать его любым именем). Сделайте это в обоих проектах и ​​поместите туда interface.aidl.Он появится в проводнике пакетов обоих проектов, и когда вы измените его в одном проекте, будет обновлен и другой.

В общей папке с исходным кодом я поместил interface.aidl в пакет с тем же именем, что исервис.

Если вы используете Ant для сборки, он становится немного сложным, так как по умолчанию ant_rules.xml не поддерживает две папки aidl, и вам придется изменить свой build.xml довольноНемного добавьте новую цель и все ее зависимости.

Я запустил свой проект, адаптировав примеры из главы 17 из «исходного кода загрузки» здесь:

текст ссылки

...