1

これはメモリベースの IPC ( LocalService の例と同様) に関するものですが、同じプロセスで実行されている 2 つのアプリの場合です。

2 つのアプリ ( App1、 ) と、両方のアプリのいくつかのインターフェイスと抽象クラスを定義App2する共有プロジェクト ( ) があります。Shared

Shared (regular Java project, references android.jar)
    - abstract myAbstractService
    - Binder myBinder
App1 (Android Project, references Shared)
    - MainActivity
App2 (Android Project, references Shared)
    - myService extends myAbstractService

両方のアプリが同じプロセス (my.processで定義されている<application>) 内で実行され、 がApp2発行されcom.www.app2.myServiceます。

<-- Both Apps run in the same process -->
<manifest <!-- *snip* --> android:sharedUserId="my.shareduser">
    <!--  ... -->
    <application <!-- *snip* --> android:process="my.process">
        <-- App2 exports the service -->
        <service android:name="com.www.app2.myService" android:exported="true">
            <intent-filter>
                <action android:name="com.www.app2.myService" />
            </intent-filter>
       </service>

これは要約ですmyAbstractServicemyServiceまだ新しいものは何も追加していません):

abstract public class GameClient extends Service
{   
    private static final String LOGTAG = "GameClient";

    private myBinder binder = new myBinder();

    public IBinder onBind(Intent intent)
    {
        Log.d(LOGTAG, "onBind()");

        return this.binder;
    }

    public class myBinder extends Binder
    {
        public void sendMessage()
        {
            Log.d(LOGTAG, "sendMessage()");
        }
    }
 }

myService(App1)から (App2)にバインドしようとするとMainActivity:

public void onServiceConnected(ComponentName name, IBinder service) 
{
    Log.d("MS", service.getClass().toString());
    main.this.t = (myBinder) service; // Exception in this line of course
}

例外があります:

DEBUG/MS(5464): クラス com.www.shared.myBinder
エラー/AndroidRuntime(5464): java.lang.ClassCastException: com.www.shared.myBinder

両方のアプリが同じプロセスで実行されるため、メモリ結合通信が機能するはずです (少なくとも私はそう思いました)。かなりの数のメッセージを送信するため、メッセージベースまたはブロードキャストベースの通信を使用したくありません。
同じクラスに 2 つの異なるクラスローダーが使用されているために、この例外が発生したのではないでしょうか? このアプローチは単に不可能/間違っているのでしょうか、それとも何か不足していますか?

更新:
私の目的は、App1 が他のモジュール (アプリ) の委任および開始アプリケーションとして使用される、非常にモジュール化されたアプリケーションを作成することです。App1それに依存するすべてのアプリ を同梱したくないので、独自のアプリにしました。

3 番目のアプリ (App3、Android プロジェクト) があるとします。App2 と App3 は両方とも App1 によって開始されます (接続のセットアップを担当しますが、App2 と App3 は異なるアプリケーション ロジックを提供します (ただし、同じインターフェイスを持ちます))。

もう一度考えてみると、これはAndroidライブラリでも解決できると思います(App1とSharedがライブラリとしてマージされ、このライブラリのアクティビティを開始し、結果を待っています) App2? App3ただし、データは分割可能ではなく (ネットワーク接続)、このライブラリを Android マーケットで独立して配布する方法がわかりません (そこに公開されていますが、ライブラリもインストールするように依頼します) App2App3これはその問題をまったく解決しますか?

4

3 に答える 3

3

2 つのクラス ローダーが関係しているため、この例外が発生します。

次の 2 行のコードを追加しました。

@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
    ...
    Log.e(TAG, "Expected class loader: "+myBinder.class.getClass().getClassLoader());
    Log.e(TAG, "Class loader: "+service.getClass().getClassLoader());
    ...
}

そして、これらのログを受け取りました:

Expected class loader: java.lang.BootClassLoader@4001bdb0
Class loader: dalvik.system.PathClassLoader[/data/app/com.inazaruk.shared.service-2.apk]

ログから、別のクラスローダーが使用されたことは明らかです。App11 週間後に別のバージョンのクラス (またはインターフェイスを介して直接的または間接的にmyBinder渡される他のクラス) を使用してアプリケーションをインストールできたので、これは実際には理にかなっています。myBinder



更新:
シナリオでは Android ライブラリを使用する必要があります。Android ライブラリは、それらを参照するアプリケーションに直接埋め込まれていることに注意してください。それらは個別に配布されません。これは、 Android ライブラリが単純な jar とどのように異なるか、およびその他の関連するニュアンスを説明する私の投稿です。

最終的な Android アプリケーションには、それが使用するモジュールのみが含まれているため、Android ライブラリには依然として高度なモジュール性があります。しかし、これは実行時のモジュール性ではなく、コンパイル時のモジュール性です。

ただし、Android ライブラリにはいくつかの問題があります。

  1. AndroidManifest.xmlライブラリのすべてのコンポーネントの宣言を Android アプリケーションのにコピーする必要がありますAndroidManifest.xml
  2. 現在、ライブラリはカスタム xml 属性をサポートしていません (こちらこちらの記事を参照してください)。
  3. 現在、ライブラリはアセットをサポートしていません (こちらの投稿を参照してください)。

#1はすぐに修正される予定です(ビルドサポートロードマップによる)。#2 と #3 は、SDK プラットフォーム ツールの次のリリースで修正される可能性があります。

于 2011-07-14T19:41:28.630 に答える
2

少し前にこれを自分で試してみました:別のアクティビティからローカルサービスにバインドするときに ClassCastException で同様の質問が以前に尋ねられましたhttps://stackoverflow.com/questions/3162538/2-apks-running-in-1-process-sharing-code -and-data . 最終結果はほぼ同じです。クラス ローダー階層の性質上、プロセスの共有はコードの共有と同じではありません (J2EE クラス ローダーの分割方法と同様)。

クラスは異なる DEX ファイルから取得されているため、技術的に言えば、インターフェイスが同じであっても、クラスは異なります。私はあなたがやりたいことが可能だとは思わない: 私はあなたの将来に AIDL を見ます。

于 2011-07-14T20:01:31.060 に答える
0

名前空間「com.www.shared」に「myBinder」というクラスがありますか? それが探しているものであり、そこにないと言っているからです。クラスがあるようですが、それはどの名前空間にありますか?

于 2011-07-14T14:25:32.990 に答える