4

私はAIDLインターフェースで壁全体を突き刺しました。サードパーティのアプリケーションを介して制御する必要のあるアプリがあります(これを十分に制御できるので、必要なものをアクティビティに実装するように依頼できます)

もともと私のアプリはインターフェースとすべてを備えたアクティビティでしたが、バックグラウンドサービスに変更し、テストのために、サービスアプリをバックグラウンドで開始するためのダミーアプリを作成しました。

ここで、サービスからのメソッド呼び出しを要求する方法が必要です(主に、start、stop、sendData)。両方のアプリの.aidlファイルを作成しました。aidlファイルは1つのメソッドのみを実装します(これは、ここでの他の質問の礼儀です)。

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

パッケージが「foo.otherapp」であることを除いて、他の援助は同じです。私がオンラインで見つけた実装には、両方のaidlファイルに対して同じパッケージがありましたが、これはエラーを引き起こします(名前空間とパッケージが嫌いなので、これは私の側の問題だと思います。それらを変更します、私はそれを行うことができます)

計画では、このメソッドを使用して文字列をサービスに送信し、事前定義された文字列を切り替えて正しいメソッドを呼び出すだけでした(使用法が改善されれば、3つの異なるメソッドを実装することもできます)。

とにかく...エイドルを接続できません。「サービスインテントを開始できません」というエラーが表示されます。

{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";
    }
};

そして最後にマニフェストファイル。

実際、エイドルを扱うときにマニフェストファイルに何かを追加する必要があるかどうかはわかりません。一例では、これを見ました。

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

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

エラーはどこにでもあると思います。私はこれをチューインガムとバンドエイドでセットアップしようとしてきました。私はこれのいくつかの基本的な概念を誤解したと思います。

とにかく、どんな助けでも大歓迎です。

前もって感謝します!

4

2 に答える 2

3

正確な解決策を見つけたので、自分の質問に答えることにしました。

マイ ライフ ウィズ Android

ソースをコピーして貼り付け、パッケージ名と関数名を正しく変更するだけですべてが機能しました(これを独自のプロジェクトに実装していると仮定します)

クライアント フォルダーからのソースはクライアント アクティビティに移動し、serviceimpl はサービスに移動します。「サービス アクティビティ」は必要なかったので、省略しました (とにかく、実際には呼び出されないようです)。

複数のリンクを投稿するほどの評判はないので、ページの上部からソースを取得できます。

「更新: Android SDK 1.5 の更新されたサンプル プログラムを確認してください。」

于 2011-01-18T11:52:44.517 に答える
1

私もこれに苦労しました。サービスとテスト アプリの両方で RemoteInterface.aidl に同じパッケージ名が必要であるというあなたの推測は正しいです。

Eclipse で開発している場合、秘訣は共通のソース フォルダー (両方のプロジェクトに共通) を用意することです。このフォルダーを両方のプロジェクトの外側とビルド プロパティ/ソース内に作成し、[ソースのリンク] をクリックして、共通の場所を参照します。ソース。(任意の名前を付けることができます) これを両方のプロジェクトで実行し、そこに interface.aidl を配置します。両方のプロジェクトのパッケージ エクスプローラーに表示され、一方のプロジェクトで変更すると、もう一方のプロジェクトも更新されます。

共通のソース フォルダーに、interface.aidl をサービスと同じ名前のパッケージに入れました。

Ant を使用してビルドしている場合、デフォルトの ant_rules.xml は 2 つの aidl フォルダーをサポートしていないため、少し注意が必要です。また、build.xml をかなり変更して、新しいターゲットとそのすべての依存関係を追加する必要があります。 .

ここの「ダウンロードソース」から第17章のサンプルを適応させることで、プロジェクトを進めました。

リンクテキスト

于 2011-01-11T12:34:18.480 に答える