本日 5月18日 Google I/Oのキーノートにて、KotlinがAndoirdの開発言語 として正式サポートされ、さらに今度 Kotlinを主要開発言語として 採用していくことが発表されました。
今まで、Kotlinを使ったことがなかったので、 早速試してみました。
part0 Andoird Studioの導入
Kotlinの開発は、Android Studioで行えます。 公式ページから一式をダウンロード・展開して /usr/local あたりに設置しておきます。
/usr/local/android-studio/bin/studio.sh
から起動できます。 毎回スクリプトを呼び出すのは面倒なので
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=AndroidStudio
Comment=AndroidStudio
Exec=/usr/local/android-studio/bin/studio.sh
Icon=/usr/local/android-studio/bin/studio.png
Terminal=false
こんな感じの AndroidStudio.desktop という名前で保存して
アイコンでメニューバーなどに登録しておきます。
part1 Kotlinサポートの追加
Kotlin用プログラインの追加は簡単でした。 まず、AndroidStudioの Welcomeウインドウで Configure > Plugins を開き、
下部の Install JetBrains plugin から Kotlin を検索すれば すぐに見つかるのでインストールします。
part2 Kotlin準備
現時点ではじめから KotlinベースでAndroidアプリ用のプロジェクト を立ち上げられるような画面は見当たりませんでした。
ただ、Kotlinは自称Javaと100%互換ということで javaのソースコードを Kotlin に変換することができます。
というわけで、まずは普通に従来通り Androidアプリプロジェクトを 立ち上げ、生成される MainActivity.java を kotlin に変換すれば いいみたいです。 javaのソースファイルを選択して 上部メニューの Code > Convert Java File to Kotlin File
で変換できます。
変換できたら
Tools > Kotlin > Configure Kotlin in Project
で依存関係の情報などをプロジェクトに追記してくれます。
ここで Gradle Scrpt の app ファイル先頭に
apply plugin: 'kotlin-android-extensions'
を追加しておいてください。 これを追加すると kotlin から Androidのリソースデータへアクセスする際に いろいろと便利な記法が可能になります。 これを記述しないままそのあたりに転がっているサンプルをコピーすると
Unresolved reference: kotlinx
と import に失敗していまうのでとりあえず書いておけばいいと思います。
part3 ことりんはろわ
準備が終わったのでとりあえずHelloWorld代わりに何か ビルドしてみます。
まずはレイアウトを用意して
import kotlinx.android.synthetic.main.activity_main.*
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main);
mytext1.setText("hiroumauma @ Canter");
mybutton1.setOnClickListener {
Toast.makeText(this, "Kotlin!!", Toast.LENGTH_SHORT).show()
};
}
}
ソースコード中の セミコロンは本来不要ですが、C出身プログラマなので 脊髄反射で入力してしまっています…。 まぁ、こんな感じで書いてビルドすると…
おぉ〜 動きました。
ソースコードを見ればわかるようにシンプルに書くのを良しとする 言語みたいです。
Javaなら
TextWidget textWidget1 = findViewById(R.id.mytext1);
textWidget1.setText("hoge");
のようになるかと思いますが 先ほどの
kotlin-android-extensions
が効いている場合
import kotlinx.android.synthetic.main.(レイアウト).*
が使えるようになり ソースコード中に直接 mytext1 mybutton1 を書いて書き換えなどができるみたいです。
逆に Java風に
var text1 = findViewById(R.id.mytext1) as TextView;
text1.setText("test");
とするとコンパイルは通りますがうまく動きません。 Kotlin は NULL に対して厳しい姿勢をとっているので ( ´∀`)<ぬるぽ が発生しないようになっています。 そのために NULLを取りうるのかどうかなどでちょっと記述が変わります。 上記コードは
kotlin.TypeCastException: null cannot be cast to non-null type android.widget.TextView
のラインタイムエラーになります。 Javaの感覚で書くと結構アラートいっぱいになってしまいました。
まぁ初日でまだろくに文法もさらっていないので仕方ありません。 パッと見た感じではJavaのソースコードより随分好感が持てるソース の見た目をしているのでもうちょっと情報が揃ったらちゃんと 覚えたいと思います。
機械変換時のメモ
javaのソースコードが kotlin に変換できるので 勉強がてらに今まで書いた自分のコードをいくつか変換してみました。
例えば ミュージックプレーヤアプリの RootMenuクラスを変換すると 変換はできますが一部赤線が入ります。
Java の
public class RootMenu extends Fragment {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
@Override
public View onCreateView((LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.menu, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
・
・
・
}
こういう書き方の部分は
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
ここがマズいので赤線が入ります。 曰く"初期化されてない"そうです。
lateinit internal var mSectionsPagerAdapter: SectionsPagerAdapter
lateinit internal var mViewPager: ViewPager
変換後 lateinit をつけてやると赤線が消えました。
こんな感じで機械変換でたいていうまく行きますが ちょこちょこと問題が発生するのでちまちま直すと…
Java / Kotlin 混在のコードで普通に動きました。