LoginSignup
6
8

More than 5 years have passed since last update.

AIDL がメソッドのオーバーロードを出来ない問題を何とかする

Posted at

AIDL では、メソッドのオーバーロードが出来ません。

つまり、以下のような AIDL はコンパイルできません。

BadAIDL.aidl
interface BadAIDL {
    void doSomething();
    void doSomething(int flags);
}

これで何が困るかといえば、呼び出される側のアプリをアップデートして IPC のインタフェースを変更出来ないということです。呼び出し側のアプリの改修を待たなければ、IPC はメソッドの実装がないものとして扱われAbstractMethodErrorを吐いてクラッシュします。

ところが、このインタフェースの実装を工夫することで、擬似的ながらインタフェースのオーバーロードが可能になります。

オーバーロードができているように見せるハック

あるバージョンでは、以下のように AIDL が定義されているとします。

SomeAIDL.aidl
interface BadAIDL {
    void doSomething();
}

この AIDL に従って実装を以下のように記述します。

SomeIPCHandler.java
public class SomeIPCHandler extends SomeAIDL.Stub {
    public void doSomething() {

    }
}

ここで、次のアップデートで AIDL を変更してみます。

SomeAIDL.aidl
interface BadAIDL {
    void doSomething(int flags);
}

すると、実装も以下のように変更が必要になります。

SomeIPCHandler.java
public class SomeIPCHandler extends SomeAIDL.Stub {
    public void doSomething(int flags) {

    }
}

ところが、IPC の呼び出し側は以前のバージョンのままの場合、このままでは存在しないメソッドを呼び出すことになります(古いバージョンの呼び出しは古いインタフェースで判断されるので、実装がないエラーとなる)。

そこで、以下のようにオーバーロードを試みます。

SomeIPCHandler.java
public class SomeIPCHandler extends SomeAIDL.Stub {
    public void doSomething() {

    }

    public void doSomething(int flags) {

    }
}

Java ではオーバーロードそのものですので、IPC でもしっかり古い方のdoSomething()が呼び出されます。
AIDL 上にはdoSomething()の定義は消滅していますが、問題なく呼び出されているはずです。

これで、AIDL のバージョニングによる互換性問題が解決出来ました。

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8