TitaniumのAndroid用モジュールを作る その3

TitaniumのAndroid用モジュールを作る その1
TitaniumのAndroid用モジュールを作る その2
の続きです。

公式サイトのドキュメントのほぼ直訳ですが若干訳が怪しい箇所があって読みづらいかもしれません・・・

モジュールとプロキシの生成

プロジェクトの初期生成の一部として TitaniumはExampleプロジェクトで使用される2つのクラスを生成します

モジュールの例: src/org/appcelerator/calc/CalcModule.java
プロキシの例: src/org/appcelerator/calc/ExampleProxy.java

Android Titanium API

モジュールとプロキシ (Kroll part 1)

  • モジュールは常に同じ名前でアクセスできる静的なトップレベルのAPIです。Titanium.UIとTitanium.AppはトップレベルTitaniumオブジェクトの下にあるモジュールの例です。
  • プロキシはモジュールや他のプロキシのAPIを通して生成される動的なオブジェクトです。Titanium.UI.createViewでネイティブのViewを生成したとき、そのViewオブジェクトはプロキシです。
  • モジュールとプロキシは両方ともメソッド、プロパティ、定数、getter/setter をjavascriptAPIとして公開出来ます。

モジュール

プロキシ

メソッドとプロパティの公開 (Kroll part 2)

メソッド
プロキシやモジュールのメソッドは@Kroll.methodアノテーションをつけて公開されます。
以下はシンプルな例です

@Kroll.method
public String getMessage() {
    return "Hello World";
}

公開するメソッドが現在のActivityを必要とする場合は最初の引数にKrollInvocationオブジェクトを追加することができます。

@Kroll.method
public String getMessage(KrollInvocation invocation) {
    Activity activity = invocation.getTiContext().getActivity();
}

メソッドには他の多くのプションがあるので@Kroll.methodjavadocを参照してください

プロパティ

プロパティを公開する方法は2つあります

  1. getter/setterメソッドに@Kroll.getProperty@Kroll.setPropertyアノテーションをつける方法。getter/setterメソッドはKrollメソッドとして公開出来ます。(これは普段Titaniumで行われているパターンです)
  2. オブジェクトの変数に@Kroll.propertyアノテーションをつける方法(このパターンはリフレクションを使うので少し遅いです)

この例では、同じ名前のメソッドを公開するだけでなく、messageプロパティのgetterと​​setterを公開しています

@Kroll.getProperty @Kroll.method
public String getMessage() {
        return "Hello World";
}
@Kroll.setProperty @Kroll.method
public void setMessage(String message) {
    Log.d(TAG, "Tried setting message to: " + message);
}

javascrtiptでは以下のように使うことができます

var object = //..
object.message = "hi"; // or
object.setMessage("hi");

定数

定数は@Kroll.moduleの静的プロパティです。@Kroll.constantアノテーションが付けられた変数はstatic finalである必要があります。以下は例です。

@Kroll.module
public class MyModule extends KrollModule {
    @Kroll.constant
    public static final int CONSTANT = 100;
}

定数は直接参照することが出来ます:Ti.My.CONSTANT == 100

ビュー

Titaniumのビューは2つのクラスを持つ必要があります

  • ビュープロキシ:TiViewProxyのサブクラス
    • ビューのメソッドとプロパティのJavascriptへの公開に責任があります。(通常のプロキシと同様の振る舞い)
    • TiUIViewの新しいインスタンスを返すTiUIView createView(Activity activity)をImplementsします。
    • 多くの場合、UIスレッドからUIViewを呼びたくなるでしょう。その場合は@Kroll.method#runOnUiThreadを参照してください。
  • ビューの実装: TiUIViewのサブクラス
    • ViewインスタンスかコンストラクタまたはprocessPropertiesでsetNativeViewを呼ぶ必要があります。
    • ビューの実装クラスはビュープロキシからのデータ取得とそれが公開されているネイティブのViewに直接それを適用するための責任があります
    • クラスはユーザーがプロキシにプロパティを設定したことを通知するpropertyChangedとprocessPropertiesを任意で実装出来ます。

簡単な例としてButtonProxytTiUIButtonでのButtonの実装を参照してください。

HeavyweightなWindowとLightweightなWindow

ユーザーがTitanium.UI.createWindowAPIでウインドウを生成する時、"heavy weight"ウインドウにするべきかどうか判断するためのいくつかのチェックが実行されます。

  • これらのプロパティを持つ場合はheavyweightなウインドウです:fullscreen, navBarHidden, modal, windowSoftInputMode,またはtabOpenプロパティがtrue
  • そうでなければlightweightなウインドウです
  • Heavyweightなウインドウは新しいActivityをスタックに生成し、そして常に自身のために新しいJavascriptコンテキストを生成します。
  • Lightweightなウインドウはフルスクリーンビューを生成します(呼び出し元のコードと同じActivity)。urlプロパティが設定されている場合、ウインドウのために新しいJavascriptコンテキストも生成されます。

スレッドセーフ

メソッドやプロパティがあらゆるJavascriptコンテキスト(と潜在的なあらゆるActivityやスレッド)から呼び出す事ができるので、APIを設計する際のスレッドセーフを意識することが重要です。

メソッドがUIスレッドで実行されるのを保証するために@Kroll.method#runOnUiThreadを使うことができます。以下はサンプルです。

@Kroll.proxy
public class MyProxy extends KrollProxy {
  @Kroll.method(runOnUiThread=true)
  public int doSomething() {
    return 100;
  }
}


3回に分けてモジュール作成のドキュメントを訳したり手順を追ってみましたが、ざっくり訳してみることで理解が深まったと思います。

次回はgithubで公開されているサンプルなどを参考に実際にViewのモジュール作成やモジュールからのActivityの呼び出し等をやてみようと思います。