Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

概要

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相当のことはできない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away