Javaで試行錯誤の際のTips : Java Api Examples #ことクロ9

"Kotlinでスマートフォン・クロスプラットフォーム開発の試行錯誤(人柱)の記録メモ"、
略して、"ことクロ"シリーズ　その9。

#1) "このAPI、どう呼べばいいのか?"などなどの試行錯誤
マイナーな実装案件、例えば、Android/iOS両対応のクロスプラットフォーム開発をRoboVMで行う*(さらには言語はKotlin)*、では、インターネットの情報が頼り。欲しい情報は、一般論ではなく、具体的な実装例。

とりあえず、ぐぐりながら前に進むうちに、programcreekなるサイトの以下にたどり着く:


![スクリーンショット 2015-11-28 9.37.54.png](https://qiita-image-store.s3.amazonaws.com/0/16455/b2d2e5f9-cd2a-eb9c-6d55-42633e6257fd.png) => [リンク先](http://www.programcreek.com/java-api-examples/)

*#2008年からある、けっこう古株なので、知ってる人は知ってるのだろう。自分は{知らな|覚えていな}かった。*
ちなみにPython版などもある(内容は未検証):
![スクリーンショット 2015-11-28 9.39.50.png](https://qiita-image-store.s3.amazonaws.com/0/16455/f46528dd-8786-815f-ddc5-e042d8293a55.png) => [リンク先](http://www.programcreek.com/python/)

要するに、Java APIとして公開されているものの実装例をキーワード検索してインデックスしているサイトらしい。実装例の数別にランキングされていて、上位10000件が以下から辿れる

http://www.programcreek.com/java-api-examples/?action=index

自分が欲しかったrobovmのAPI実装例は、3520番台にランキングされていた(カッコ内が実装例の件数):

```
3521. com.vividsolutions.jts.geom.Coordinate	(143) 
3522. java.io.FilterWriter	(143) 
3523. org.apache.http.NoHttpResponseException	(143) 
3524. com.badlogic.gdx.backends.iosrobovm.IOSApplication	(143) 
3525. org.springframework.beans.factory.support.BeanDefinitionRegistry	(143) 
3526. com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration	(143) 
3527. org.eclipse.debug.core.ILaunchConfigurationType	(143) 
3528. javax.lang.model.type.TypeKind	(143) 
3529. net.minecraft.entity.projectile.EntityArrow	(143) 
3530. android.text.style.UnderlineSpan	(143) 
```

いろいろありそうなのが分かるだろう。

Javaでまさしく今、試行錯誤中の人は適宜参考して欲しい。
以下は、、Android開発に自信がある人がクロスプラットフォーム開発環境RoboVMでiOS開発に乗り込むためのおまけ記録:

#2) (メモ書き)Java Api Examplesにたどり着くまで

##2-1 先人が倒れてもRoboVMで人柱するぞ　*(ぐへへ)*。

RoboVMのような新参者にも、人柱した先人はいるもの。その時々の人柱の結果は、必ずしも肯定的なものではない*(...というか、疲れたとか大変とかいう情報が多い)*。

例えば、そのまんまのタイトルの : **[結局RoboVMは使うのを辞めました。](http://aroundthedistance.hatenadiary.jp/entry/2015/04/27/012304)**


**それでも**RoboVMを使おう、という自分の頭の中を要約:

- RoboVMは、Android開発者に馴染みの深いAndroidStudioベース。
- 現状のRoboVMはiOS向けのUIデザインをXCodeに委ねる方針(@IBOutlet等のアノテーション経由)。
- 少なくとも入門段階では、UIデザインをコードで書いた方が良いと思う(すなわち、RoboVMのみを使用して、iOS開発を学んでいく。)
- ほんとに生産性を高めるためには、クロスプラットフォーム開発向けのデザイン支援ツールが欲しいところ(イメージはHTMLに対するslimとかjadeとかのようなもの)
- といっても、クロスプラットフォーム開発向けのデザイン支援ツール、DIとかの兼ね合いを考えると意外に難しいのでは。
- いやいや、KotlinでDSL作ってしまえば、あんなことやこんなことも*... グヘヘ...*

*(あまり盛り上がりすぎると後で失望がおおきいので、ここで止めて、コードの方に戻る)*

*# 以下はKotlinのコードだけれど、Javaでも共通する内容。Javaで以下と同趣旨のコードは、[RoboVMまとめ](http://qiita.com/garsue/items/0487aae7a4e45e313a36)などにある。RoboVMまとめは、数カ月前までのRoboVMの状況かいろいろ記されているので、RoboVMで人柱したいJavaの人もKotlinの人も適宜参考にしよう。*


##2-2 RoboVMが自動生成するコードを眺める。
 
自動生成されるコードはぱっと見、難しくはない。

```MyViewController.kt
package com.mycompany.myapp

import org.robovm.apple.uikit.UILabel
import org.robovm.apple.uikit.UIViewController
import org.robovm.objc.annotation.CustomClass
import org.robovm.objc.annotation.IBAction
import org.robovm.objc.annotation.IBOutlet

@CustomClass("MyViewController")
class MyViewController : UIViewController() {

    private val counterStore = CounterStore()

    @IBOutlet
    private val label: UILabel? = null

    @IBAction
    private fun clicked() {
        counterStore.add(1)
        label!!.text = "Click Nr. " + counterStore.get()
    }
}
```

@CustomClass等のアノテーションが、名前空間org.robovm.objc.annotationと紐付いていることが分かる。名前の通りこれは、Objective-Cオブジェクトに属しており、plist(XMLファイル)経由で、XCodeによって制御される。もちろん、こちらを出発点にして行っても良いのだけれど、iOS開発未熟者としては、全体像が見通せない予感がする。ということで、すべてをコード(私はKotlin)で書いていく。

なお、CounterStoreというのは、以下のフォルダ構成にあるように、Android側との共通モジュールにあたるCore配下にある。

[参考] フォルダ構成 : ![スクリーンショット 2015-11-27 7.12.57.png](https://qiita-image-store.s3.amazonaws.com/0/16455/72962371-b4fc-8a0c-92aa-10a1c0fb62c4.png)


##2-3 UI要素をコードで追加開始(同類roboscalaを参考に。)

残念ながら、github等には、現バージョンのRoboVMで動くKotlinのコードは無いようなので、roboscalaのコードを参考にさせてもらった。こちら、Pure ScalaでRoboVM開発を進めようと頑張っているプロジェクト(gradleではなくsbtベース)。
https://github.com/roboscala


```MyViewController改1.kt
package com.myapp

import org.robovm.apple.uikit.* // UILabel,UIViewController etc.
import org.robovm.apple.foundation.* // NSSet etc.
import org.robovm.objc.annotation.* // CustomClass,IBAction,IBOutlet
import org.robovm.apple.coregraphics.CGRect


@CustomClass("MyViewController")
class MyViewController : UIViewController() {
    private val counterStore = CounterStore()

    // Code Only.
    val textField = UITextField(CGRect(20.0, 190.0, 280.0, 48.0))
    override fun viewDidLoad() {
        textField.setContentVerticalAlignment(
                  UIControlContentVerticalAlignment.Center)
        textField.setBorderStyle(UITextBorderStyle.RoundedRect)
        textField.setClearsOnBeginEditing(true)
        textField.text = "ここに文字列を入力"
        getView().addSubview(textField)
    }

    // XCode Storyboard based code
    @IBOutlet
    private val label: UILabel? = null

    @IBAction
    private fun clicked() {
        counterStore.add(1)
        var name = textField?.getText() ?: "未設定"
        label!!.text =  "${counterStore.get()}回目:${name} です。"
    }
}

```

"Code Only"以下のところで、TextField要素を追加している。元のScalaのコードとの違いは、CGRectの引数が整数値(20)であるか実数値(20.0)であるか、くらい。

エミュレータでの実行例:
![スクリーンショット 2015-11-27 21.27.10.png](https://qiita-image-store.s3.amazonaws.com/0/16455/b7cf720e-d94f-54a6-c355-17d681f435d4.png)


##2-4 さて、すべてをKotlinコードにする。DIもしよう*...ぐぬぬ。*

ボタンクリック時のイベント処理のpure scalaコードはなかった。ということでjavaの実装例をググって
見て、変換をかけ(RoboVM含むIntelliJ系のツールでは、Java->Kotlinの自動変換が可能)、動くコードにしていく。

```kotlin
        btn1.addOnTouchUpInsideListener(object:OnTouchUpInsideListener {
            override fun onTouchUpInside(c:UIControl, e:UIEvent) { onClicked() }
        })
```

...objectとかなるほどだけど、なんかかっこ悪いなぁ。*...ぐぬぬ。*

さて、DIは、先人に学んでこんな感じで

```kotlin
    //DIによる初期化
    private val context = getApplicationContext()

    instantiateInjector(con)

    fun instantiateInjector(context :android.content.Context) {
        val appModule = AppModuleImpl(context)
        val dataModule = DataModuleImpl(appModule)
        ...
        Inject.instance = InjectorImpl(appModule, domainModule...)
    }
```

なんとかなった。だけれど、こちらは、Android環境向けのDI実装。iOSにも対応できるDI実装にするにはどうしたら*...ぐぬぬ。*


##2-5　*...ぐぬぬ*の壁、Java Api Examplesと共に乗り越えられるか。

人柱実装、あれもこれもこうしてああして、*... グヘヘ...*と始めた話が、*...ぐぬぬ。*となるのはよくある話。

そんな時に、robovm.apple.uikit.UIButton(uikitのroboVM社によるJavaラップ)でぐぐったら、Java Api Examplesにたどり着きました。

> [Java Code Examples for org.robovm.apple.uikit.UIButton](http://www.programcreek.com/java-api-examples/index.php?api=org.robovm.apple.uikit.UIButton)

ああ、こんなマイナーな話の実装例が10も出でくるなんて、素敵。


......単にググる時間節約出来るだけなんだけど、Java&JVM言語で試行錯誤のお供にはなってくれるね。