15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ClojureをAndroid StudioでビルドしてAndroidで動かす

Last updated at Posted at 2017-12-12

概要

ClojureのGradle用のプラグインとして、gradle-clojureというものが存在する。私はそのgradle-clojureをベースにAndroidのビルド用の機能を作成しており、本記事ではその紹介を行う。
現状はバージョン0.1くらいの完成度なので実用段階ではないが、試してフィードバックをいただけると嬉しい。

Clojure on Androidの現状と問題点

実は既に、Clojure on Androidというプロジェクトが数年前から存在し、AndroidでClojureを使う場合は、Clojure on Androidプロジェクトの成果物を使うのが定番となっている(React Native + clojurescriptを使う方法もあるが、ここでは言及しない)。

Clojure on Androidでは、leiningen + lein-droidプラグインを使ってビルドを行う仕組みなのだが、現状以下の問題点がある。

  • Androidのビルドシステムの機能をlein-droidで独自に実装し直しているので、Androidビルドシステムの変化に追従するのにコストがかかる。
  • 開発が止まっている。
    (しかも、最新のlein-droidはこのパッチを当てないとビルドができない。)
  • Androidの標準ビルドシステムはGradleなので、整合性が悪い。

そこで、gradle-clojureにAndroid用のビルド機能を追加することにした。

Android Studioでビルドできるサンプルアプリ

gradle-clojureのAndroid対応と、そのAndroid対応版でビルドできるサンプルプロジェクトを用意した。

$ git clone https://github.com/anolivetree/gradle-clojure-android-sample.git

サンプルプロジェクトをビルドし実行すると、以下のような表示になる(はず)。

clojure-android.png

アプリを起動すると、http://www.yahoo.co.jp から(Clojureのライブラリである)http-kitを使ってデータを取得し、TextViewに表示する。上部のGETボタンを押すと、Logcatに"hello"と教示される。

もしClassNotFoundExceptionでActivityの起動ができない場合は、

  • targetSdkVersionを下げる
  • ^によるtype hintを付けまくる

と、解決するかもしれない。

nREPL

サンプルアプリにはnREPLを組み込んでいて、アプリの起動後数秒でnREPLが接続可能となる。nREPLを起動するためのソースは、nekoのソースを借用している。

nREPLに接続するには、

$ adb forward tcp:9999 tcp:9999

としたのち、lein replで9999ポートに接続すると、REPLが動く。

$ lein repl :connect 9999
Connecting to nREPL at 127.0.0.1:9999
REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
Dalvik 0.9
FileNotFoundException Could not locate clojure/java/javadoc__init.class or clojure/java/javadoc.clj on classpath.  clojure.lang.RT.load (RT.java:462)
#object[clojure.lang.Namespace 0xd6f2923 "user"]
Error loading namespace; falling back to user
nil
user=> (+ 1 2)
3
user=> 

nREPLは軽い動作確認しかしていないので、もしかしたらちゃんと動かないかもしれない。

今後の課題とTODO

たくさんある。

Clojureのバージョンが古い

Clojure on Androidプロジェクトで、素のClojureにAndroid対応を行ったClojureを提供しているが、バージョンが1.7.0と古い。Android用の変更を反映した1.8(もしくは1.9)を用意したい。

クラスの動的なロードが遅い

クラスの動的なロード時に

  1. ClojureのコンパイラがJava bytecodeを作成
  2. dxでDalvik bytecodeに変換し、ロード

としているためなのだが、非常に遅い。将来的には直接Dalvikのbytecodeを出力したい。

JavaからClojureで作成したクラスの呼び出しができない

現状は先に.javaをコンパイルし、次に.cljのコンパイルを行っている。
そのため、ClojureからJavaの呼び出しは可能だが、逆はできない。

library project, test projectの対応

試していないが、きっと動かないと思う。

未使用ファイルもすべてAOTということはできない。

lein-droidにある、:aot :all-with-unused相当のことはできない。

15
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?