18. interface Some {
String method_1();
String method_2();
String method_3();
String method_4();
String method_5();
}
このインターフェイスに対して
説明
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
18
19. class QuadSome implements Some {
public String method_1() {
return String.valueOf(1 * 1);
}
public String method_2() {
return String.valueOf(2 * 2);
}
public String method_3() {
return String.valueOf(3 * 3);
}
public String method_4() {
return String.valueOf(4 * 4);
}
public String method_5() {
return String.valueOf(5 * 5);
}
}
Some instance = new QuadSome();
こういう実装をしたい
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
19
20. Some instance = (Some) Proxy.newProxyInstance(
Some.class.getClassLoader(),
new Class<?>[]{ Some.class },
(proxy, method, param) -> {
int num = Integer.parseInt(method.getName().substring(7));
return String.valueOf(num * num);
}
);
動的にメソッドの実装ができる。
Proxy を使うことで
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
20
21. ⁃ Proxy は interface に対してでしか使えない
⁃ あるクラスXに対して
• メソッドの実装部分を X_0 として切り出す
• X に対するメソッドの呼び出しは X_0 を参照するようにする
• 変更したメソッドの実装部分を X_1 として切り出す
• X は最新の X_n を参照するようにしておく
もう一工夫
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
21
22. class Foo {
public int someField = 123;
public int someMethod() {
return someField + 456;
}
}
模擬コード例
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
22
23. class Foo_0 {
private Foo proxy;
Foo_0(Foo proxy) {
this.proxy = proxy;
}
public int someMethod() {
return ivar.someField + 456;
}
}
class Foo {
public int someField = 123;
private Class getDelegate() {
// return Foo_0 instance
}
public int someMethod() {
return getDelegate().someMethod();
}
}
こう変換してみる
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
23
24. public int someMethod() {
return someField + 456;
}
↓↓↓
public int someMethod() {
return someField + 789;
}
メソッドの内容を変更
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
24
25. class Foo_1 extends Foo {
private Foo proxy;
Foo_1(Foo proxy) {
this.proxy = proxy;
}
public int someMethod() {
return proxy.someField + 789;
}
}
もう一度変換すると
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
25
26. private Class getDelegate() {
File dex = findLatestDex();
if (dex != loadedDex) {
delegate = loadDex(dex);
loadedDex = dex;
}
return delegate;
}
⁃ Foo_0 と Foo_1 は別クラス扱い
• クラスがキャッシュされる問題を回避できる
委譲先を決める箇所の模擬コード
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
26
※
ここまで推測
27. 考え得る hot deploy の実現方法
⁃ Jack and Jill
⁃ デバッグ時は Class Loading の制限を解除
余談
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
27
28. ⁃ トライしていた手法
• 転送するファイルの特定方法がシンプル
• プロセスの再起動が必要
• Instant Runェ…
⁃ Instant Run
• hot swap は Activity の再起動すら不要
• (開発時とリリース時の同一性)
• (オーバーヘッド)
⁃ クラスがキャッシュされる問題さえなければ……
• さらなる改良に期待
まとめ
Copyright (C) DeNA Co.,Ltd. All Rights Reserved.
28