2011/09/20

勝手/全/超訳 Titanium Mobile Module Developer Guide for Android



以下は Module Developer Guide for Android の全訳です。 事前の許可なく勝手に日本語に翻訳しました。画像はAppceleratorのサイトへのリンクとなっています。

 オリジナルの文書のタイトルが「Titanium Android Module Developer Guide」「Titanium Mobile Module Developer Guide for Android」など複数の表記があって一定しませんが、現状の wiki ページのタイトルを使うことにします。
 iOS用の文書に比べると、簡潔にまとめられていますが、本当にガイド的な内容しかなく、実質的な情報への参照の指示がある場合がほとんどです。ですので、Android 用モジュールを作成するには、この文書だけでは不十分で、Titaniumのソースファイルの JavaDoc を見たり、Appcelerator のモジュールのサンプルを見たりする必要があると思います。また、この文書に登場する Kroll そのものについて、ほとんど説明がありません。
ともかく始めるにあたって、全体の様子を把握することは重要なので訳しておきました。


 モジュール開発しようという人たちの助けになれば幸いです。
 また、私の間違い、勘違いなど不備があると思います。お気づきの点がございましたら、ご遠慮なく、コメントしていただけると助かります。
------------

概要

このガイドは Android 用 Titanium の拡張をどう始めるかを説明します。このガイドで学ぶことは次のことです:
  • Android モジュールを作成するための環境設定をする
  • Android モジュールのビルド
  • Android モジュールのパッケージング
  • Android モジュールAPIの理解

Titanium Android Module Developer Guide

Android Module SDK 使用するには、Android SDK についての知識が必要です。このガイドは、ネイティブな Android SDK を使用するアプリケーションの作成に習熟していることを仮定します。

必須条件

  • Titanium Mobile SDK 1.5.0 以上
  • (2.5以上の)現行バージョンの Python。PATH あるいは PYTHONHOME に設定されている必要があります
    • Windowsでは、 Titanium Developer / Desktop は、Python 2.5 が同梱されていますので、特に環境設定の必要がありません
  • Oracle JDK
  • Android SDK, Prerequisite Android SDK and Android SDK の互換表に従う
  • Ant 1.7.1 以上   PATH の設定が必要です
    • もし個別に Ant をインストールしたくなければ、オプションとして Eclipse を使うことができます。

環境設定

Titanium Command-line tool の Environment Setup section の指示に従って設定してください。

モジュールの作成

モジュールを作成するためには、いくつかの引数を titanium create コマンドに渡す必要があります。つまり:
  • モジュール名  ($MODULE_NAME) と ID  ($MODULE_ID)
  • 作成するモジュールの対象となるプラットフォーム (android)
  • インストールされた Android SDK のトップレベルパス ($ANDROID_SDK)  (例えば /opt/android-sdk )
Android モジュールのためには、モジュールを作成したいと思っている親ディレクトリから次のコマンドで作成できます:
titanium create --platform=android --type=module --name=$MODULE_NAME --id=$MODULE_ID --android=$ANDROID_SDK
例として、簡単な加算と減算をおこなうモジュールを作成しましょう。モジュール名を "calc"、ID を "org.appcelerator.calc" としましょう。 Android SDK を取り出す場所を /path/to/android-sdk で指示しましょう。
titanium create --platform=android --type=module --name=calc --id=org.appcelerator.calc --android=/path/to/android-sdk
成功すれば、カレントディレクトリに calc フォルダができているはずです。

モジールプロジェクトの配置

モジュールフォルダの中には、生成されたファイルとディレクトリのツリーがあります:
  • LICENSE - モジュールの完全なライセンス文書
  • build.properties - Ant パロパティファイル。Titanium SDK と Android SDK の場所を含んでいます。
  • build.xml - メインの Ant ビルドスクリプト。これを使ってモジュールのビルド、配布、テストができます。
  • manifest -モジュールのマニフェストファイル。バージョン、作者、ライセンス、著作権、モジュール名、モジュールID、GUID とプラットフォーム情報が含まれます。
  • timodule.xml - AndroidManifest.xml に挿入されるカスタムアクティビティや一般の XMLがおかれます(詳細な文書はもうすぐできます)
  • hooks - モジュールがプロジェクトから追加/インストール/削除/アンインストールされたときに呼ばれるスクリプトのディレクトリ(作業中)
  • documentation - 生成された Markdown ファイル。モジュール用のドキュメントの例文を含んでいます
  • assets -画像などのモジュール固有のアセットがここに置かれます ( README 参照)
  • lib - サードパーティ製のJAR 依存をここに置きます。これらは、プロジェクトのクラスパスとモジュールzipファイルに自動的に追加されます。
  • src - モジュールのソースコードが置かれます。
  • example - モジュールの模範例プロジェクトが置かれます。

Eclipse 統合

Titanium はまたEclipseに直接モジュールプロジェクトをインポートするのに必要なファイルも作成します。
  • トップレベルメニューの  *File* > *Import...* をクリックします
  • *General* フォルダを展開して *Existing Project into Workspace* をダブルクリックします。
  • *Browse...*  をクリックして、  *Select root directory*  テキストフィールドを選びます
  • プロジェクトフォルダを選択します
  • *Projects* リストの中にモジュールプロジェクトが見えるはずです:

  • *Finish* を押すと、モジュールプロジェクトが Eclipse の *Package Explorer* ビューから見えるようになるはずです。

モジュール zip のビルド

dist フォルダ内の zip はモジュールの配布形式です。一般に $MODULE_ID-android-$MODULE_VERSION.zip という命名パターンに従います。
zipに含まれるのは:
  • コンパイルされた JAR 。モジュールプロジェクト由来のクラス、生成されたバインディング、リソースを含みます (src フォルダからビルドされます)
  • lib フォルダにあるサードパーティ製 JAR
  • モジュールマニフェスト。作者、バージョン、ライセンス、著作権などの配布メタデータを含んでいます。
  • モジュールの timodule.xml

コマンドラインからのビルド / Ant

PATH 上に ant があれば、モジュールのトップディレクトリから単にこれを実行するだけです。
最初のビルドのときは、次のような出力があるはずです:
$ ant
Buildfile: /Users/marshall/Code/test/test_modules/calc/build.xml
init:
  [mkdir] Created dir: /Users/marshall/Code/test/test_modules/calc/build/classes
  [mkdir] Created dir: /Users/marshall/Code/test/test_modules/calc/dist
process.annotations:
  [javac] Compiling 2 source files to /Users/marshall/Code/test/test_modules/calc/build/classes
  [javac] Note: [KrollBindingGen] Running Kroll binding generator.
  [javac] Note: [KrollBindingGen] No binding data found, creating new data file.
  [javac] Note: [KrollBindingGen] Found binding for module Calc
  [javac] Note: [KrollBindingGen] Found binding for proxy Example
compile:
  [javac] Compiling 2 source files to /Users/marshall/Code/test/test_modules/calc/build/classes
  [copy] Copying 1 file to /Users/marshall/Code/test/test_modules/calc/build/classes
dist:
  [jar] Building jar: /Users/marshall/Code/test/test_modules/calc/dist/calc.jar
  [zip] Building zip: /Users/marshall/Code/test/test_modules/calc/dist/org.appcelerator.calc-android-0.1.zip
BUILD SUCCESSFUL
Total time: 1 second

Eclipse からのビルド

PATH 上に ant がなかったり、特に Eclipse を使いたいなら、次の手順で Eclipse からモジュールをビルドできます:
  • モジュールプロジェクトの build.xml を右クリックします
  • *Run As* > *Ant Build*(1番目のオプションです)を選びます
  • 出力が Ant の場合と同じようになるはずです。

モジュールの配布

Titanium mobile アプリケーションでモジュールを使用するには、次の手順に従います:
  • モジュール zip を、Titanium アプリケーションのルートか、Titanium SDK のルートにコピーします。(訳注:様々な理由からアプリケーションルートにzipを置くのはお勧めできません
  • アプリケーションの tiapp.xml に次の XMLを <ti:app> の内側に追加します:
<!-- $MODULE_VERSION should be the same as "version" in the module manifest -->
<modules>
  <module version="$MODULE_VERSION">$MODULE_ID</module>
  <!-- For example, if we were adding the calc module: -->
  <module version="0.1">org.appcelerator.calc</module>
</modules>
  • アプリケーションコードの中で require 関数を使って、モジュールをロードします。例えば:
var Module = require('$MODULE_ID');
// For example, to load the calc module:
var Calc = require('org.appcelerator.calc');
  • 次回からアプリケーションを起動したり、ビルドしたりするとモジュールはアプリケーションに含まれるはずです。

組み込みの模範例プロジェクトでのテスト

モジュールを使いはじめる最も簡単な方法は、 example/app.js ファイルにコードを書き始めることです。example フォルダは、アプリケーションの Resources フォルダと同等に扱われます。なので、テストの過程でそこにデータファイルやほかのコードをコピーするのは自由です。
模範例プロジェクトを実行するプロセスは単純です:
  • android エミュレータを一度実行します。
  • エミュレータがブートしたら模範例アプリケーションとモジュールは好きなだけ何回でも実行できます。

Android エミュレータの実行

コマンドラインから次のコマンドをモジュールプロジェクトの中で実行します:
ant run.emulator
コンソールにエミュレータの出力を得るはずです。
Eclipse から起動環境設定する::
  • build.xml を右クリックして *Run As* > *Ant Build...* を選びます(第二オプション)
  • 新しい起動環境のための環境設定ウインドウが開きます。
  • *Check targets to execute   **dist* ターゲットのチェックを外します。   *run.emulator*  ターゲットにチェックを入れます。
  • 覚えやすいように *Launch Configuration* を run emulator という名前に変えます
  • calc モジュールの模範例のウインドウは次のようになります:

  • *Apply, then **Run* をクリックします。
  • これ以降 *Run* の *External Tools* メニュー、あるいは、ツールバーエントリーから、 *Launch Configuration* を実行できるようになります。

  • Eclipse のコンソールビューにエミュレータの出力を得るはずです。

模範例プロジェクトの実行

一度エミュレータが起動して実行されると、アンロックスクリーンが現れるまで待たなければなりません。このスクリーンでアンロックすれば、模範例プロジェクトが起動するのを確認できるはずです。
コマンドラインから次のコマンドをモジュールプロジェクトの中で実行します:
ant run
Eclipseから起動環境設定する::
上記のLaunch configuration 設定と同じ手順で、*run.emulator* ターゲットの代わりに  *run*  ターゲントを使用します。また、名前もちょっと変えて、たとえば、  *run calc project* とでも名付けましょう。
トラブルシューティング:
エミュレータが見つからなくて run* ターゲットがタイムアウトするようなら、次の2つのコマンドを使って ADB サーバをリスタートしてください:
$ $ANDROID_SDK/tools/adb kill-server
$ $ANDROID_SDK/tools/adb start-server
この時点で、モジュールの模範例プロジェクトの実行が成功していれば、エミュレータ上でデフォルトの "hello world" アプリケーションが開くはずです:

モジュールの生成と模範となるプロキシ

最初のプロジェクト作成の一部として、Titanium は模範例プロジェクトによって使用される2つのクラスを生成します:
  • モジュールクラス。例えば: src/org/appcelerator/calc/CalcModule.java
  • 模範となるプロキシクラス。例えば: src/org/appcelerator/calc/ExampleProxy.java
モジュールとプロキシが Javascript に対してどのように公開されるか、理解するために、これらを吟味しましょう。Titanium API と Kroll API の短い概説のための次のセクションへ移りましょう。

Android Titanium API

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

  • モジュールは、同じ名前でアクセルされる静的な追加のトップレベル API の場所です。Titanium.UITitanium.App は、トップレベルの Titanium オブジェクトの配下にあるモジュールの2つの例です。
  • プロキシは、動的なオブジェクトで、モジュールやほかのプロキシの API を通じてユーザにより生成されます。Titanium.UI.createView を用いてネイティブなビューを生成するとき、ビューオブジェクトはそれ自体プロキシです。
  • モジュールもプロキシもともに、メソッド、プロパティ、定数、 getter/setter を Javascript APIに公開します。

モジュール

  • @Kroll.module でアノテートし 、 KrollModule を拡張しなければなりません
  • 親モジュールを持つことができます。例えば、 Titanium.App.Properties モジュールは Titanium.App の配下にある。
  • require() で使用する一意な ID を持つことができます。
  • ( Titanium と同じレベルにして)トップレベルオブジェクトとして公開することもできます。

プロキシ

  • @Kroll.proxy でアノテートし KrollProxy を拡張しなければなりません。
  • @Kroll.proxy#creatableInModule (というアノテート)が使用されるときに生成される "create" メソッド を持つことができます
  • 組み込みイベントを管理します

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

メソッド

プロキシやモジュールのメソッドは @Kroll.method というアノテーションによって公開されます。簡単な例:
@Kroll.method
public String getMessage() {
    return "Hello World";
}
公開されたメソッドがカレント Activity を要求するなら、KrollInvocation オブジェクトを1番目の引数に加えることができます:
@Kroll.method
public String getMessage(KrollInvocation invocation) {
    Activity activity = invocation.getTiContext().getActivity();
}
メソッドには、さらに多くのオプションがあります。さらに @Kroll.method の Javadoc を参照してください。

プロパティ

プロパティはKrollで2つの異なった方法で公開され得ます:
  1. @Kroll.getProperty あるいは @Kroll.setProperty アノテーションを伴った getter/setter メソッドとして。getter/setter メソッドは、さらに Kroll メソッドとしても公開できます。(これは、Titanium でよく使われるパターンです)
  2. @Kroll.property アノテーションを伴ったオブジェクトフィールドとして。(これはリフレクションを使用するので、少し遅くなります)
この例では、message プロパティの getter/setter とともに、同名のメソッドをも公開しています。(訳注:つまり、上の1.の場合の例です)
@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);
}
Javascript側では、次のように使用されるでしょう:
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) を実装します。
    • 多くの場合、UIスレッドからUIView が呼ばれるようにしたいだろう。 @Kroll.method#runOnUiThread を参照
  • ビューの実装: TiUIView のサブクラス
    • コンストラクタでもprocessPropertiesでもViewのインスタンスとともにsetNativeViewが呼ばれなければなりません
    • ビューの実装は、ビュープロキシからデータを受け取って、ビューが公開するネイティブ View へ直接データを提供する責務があります。
    • クラスはオプションで propertyChanged や processProperties を実装することができます。これは、プロキシに対してユーザがプロパティをセットしたとき通知します。

簡単な例としては、 ButtonProxyTiUIButton におけるボタンの実装を参照してください。

重量級ウインドウと軽量ウインドウ

Titanium.UI.createWindow API でウインドウを作成できますが、そのウインドウが「重量級」であるべきか、「軽量級」であるべきか知るためにいくつかチェックしましょう:

  • ウインドウが重量級になるのは、プロパティとして fullscreen, navBarHidden, modal, windowSoftInputMode のうちいずれかを持つ場合や、tabOpen プロパティが true である場合です。
  • それ以外の場合は、ウインドウは軽量級です。
  • 重量級ウインドウはスタック上に新しい Activity と、ウインドウのための新しい Javascript コンテキストを作る
  • 軽量ウインドウは、(コードが呼ばれたのと同じ activity に)フルスクリーンビューを作ります。url というプロパティがセットされると、ウインドウのために新しい Javascript コンテキストが作成されます。

スレッドセーフ

メソッドやプロパティは、あらゆる Javasript コンテキストから(潜在的にはあらゆる Activity/スレッドから)呼び出されますから、 API をデザインする上でスレッド安全性に心を砕くのは重要です。
メソッドが UIスレッド上で実行されるようにするには、 @Kroll.method#runOnUiThread が使用できます。例:

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

1 件のコメント:

  1. AppceleratorのサイトのURLがかわってしまったので、画像のリンクが切れています。そのうち直します。

    返信削除