Androidアプリの開発がAndroid Studioのみで公式サポートされるようになってから、ライブラリがjarからaarで配布されることが多くなり、ライブラリ構成も今までよりも小さな機能単位で分割されるようになりました。
Android Studioで開発する場合はソフト側で依存関係の解決してくれるので特に問題は無いのですが、ANEを作るのはとても大変になり、もはや手作業で依存関係を調整するのは現実的ではなくなってきました。
そこで依存関係を調べてダウンロードし、展開して名前を変更してANEを作りやすくするツールを作ったので、その時の知見をここに書きます。
ツール自体は汎用性がなく公開するに耐えるような物ではないので公開する予定はありませんが、その時に利用した各種仕様や注意事項をまとめています。
自分でツールを作るのが最善の方法か分かりませんし、例えばAndroid Studioの使い方に精通すれば簡単に依存性に基づいてライブラリをダウンロードできるかもしれません。ただ、同じような問題に悩んでいる人の役に立つ可能性もあると思いこの記事を公開します。
ライブラリの依存関係はAndroid Studioの機能でもできるのですが、それを見ながら一つずつダウンロードするのは面倒なので、pomファイルを利用しました。
Android StudioはApache Mavenというプロジェクト管理ツールを使っており、それが使用する依存関係を記載したxmlファイルがpomファイルです。
例えばGoogleのライブラリについては、
「http://maven.google.com/[5]「グループパス」/「ライブラリ名」/「バージョン」/「ライブラリ名」-「バージョン」.pom」
にアクセスすればpomファイルが取得できます。
つまり「play-services-ads」のバージョン「17.2.0」なら、
http://maven.google.com/com/google/android/gms/play-services-ads/17.2.0/play-services-ads-17.2.0.pom
となります。google以外が提供しているライブラリも、Mavenを利用する物なら「http://maven.google.com/[5]」の部分をgradleに記載するURLに変更すればpomファイルが取得可能です。
pomファイルの内容は例えば
<?xml version='1.0' encoding='UTF-8'?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.google.android.gms</groupId> <artifactId>play-services-ads</artifactId> <version>17.2.0</version> <packaging>aar</packaging> <dependencies> <dependency> <groupId>com.android.support</groupId> <artifactId>customtabs</artifactId> <version>26.1.0</version> <scope>compile</scope> <type>aar</type> </dependency> <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-ads-base</artifactId> <version>[17.2.0]</version> <scope>compile</scope> <type>aar</type> </dependency> 以下略
といったものになっており、「dependencies」の部分に依存関係が記載されています。
記載されている依存関係は直接の子だけです。孫の依存関係は記載されている子ライブラリのpomファイルを参照しなければなりません。つまり、ツールを作成する場合は再帰的にpomファイルを取得して解析しなければなりません。
pomファイルの詳しい仕様はhttps://maven.apache.org/pom.html[6]で公開されています。また、実際にファイルを見るとだいたいどのような事が書いてあるか分かると思います。そこで、わかりにくい部分や注意すべき所だけ解説します。
そのライブラリがどのようなファイル形式で配布されているかです。省略されているとjarファイルです。ライブラリのファイルをダウンロードするときに必要になります。全てのライブラリがaar形式で配布されているわけではないので注意が必要です。
dependencyのversionに時々ついている[](角括弧)は正確にそのバージョンでなければならない事を意味します。他に「[1.0,2.0)」となっていれば、1.0以上、2.0未満を表すなど、数学の数値の範囲を表す記号と同様のルールがあります。特にそういった記号がなければ推奨されるバージョンを指します。
dependencyの中に「exclude」というタグがあり、ライブラリ名が記載されていることがあります。その場合はそのライブラリはさらにその下の階層の依存性から取り除かなければなりません。この処理を忘れるとライブラリ同士のバージョンなどが衝突しやすくなります。
依存関係が分かれば次はそれをダウンロードします。そのURLはGoogleなら
https://dl.google.com/dl/android/maven2/「ライブラリのグループパス」/「ライブラリ名」/「バージョン」/「ライブラリ名」-「バージョン」.「拡張子」
です。ここで「拡張子」はpomファイルのpackagingで指定された物です。
このあたりをおさえておけば、pomファイルから依存関係を割り出してダウンロードするツールが作れると思います。
ライブラリをダウンロードしたら、それをzip解凍して必要なファイルを取り出さなければなりません。
Androidで使うaarファイルの構成物の仕様は以下のページにまとまっています。
https://developer.android.com/studio/projects/android-library?hl=ja#aar-contents[21]
多くのライブラリでは
AndroidManifest.xml classes.jar /res/
をANEやAirアプリに取り込む必要があります。また、
/assets/
も必要となることがあります。他の「/libs/name.jar」や「/jni/abi_name/name.so」も必要となる可能性がありますが、私は扱ったことがないのでここでは省略します。
AndroidManifest[22].xmlの「manifest」の「package」属性にパッケージ名が記載されています。これはANEを作成するときのplatform.xmlで指定する「packagedResource」の下の「packageName」になります。例えば、play-services-adsならAndroidManifest[22].xmlは
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.google.android.gms.ads.impl" > <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.customtabs" /> </manifest>
となっているので、パッケージ名は「com.google.android.gms.ads.impl」となります。
また、このAndroidManifest[22].xmlの内容は最終的なapkのAndroidManifest[22].xmlに統合されます。特に「uses-permission」や「activity」がよく記述されているので、忘れずにAirをビルドするときのapp.xmlの「manifestAdditions」の下に付け加えなければなりません。また、異なるライブラリのAndroidManifest[22].xmlに全く同じ内容の項目がある場合には一つにまとめる必要があります。
実際にどのような項目が必要でどう統合されるかを確かめるなら、Android Studioで実際にライブラリを含むapkファイルを作成して、それをzip解凍すると統合されたAndroidManifest[22].xmlが得られます。ただし、このAndroidManifest[22].xmlはバイナリファイルになっているので、例えば https://qiita.com/red12sparrow11/items/59962c8b065860944670[25]を参考にするなどしてテキストに戻す必要があります。またこのAndroidManifest[22].xmlは変数が展開されてしまっているので、これをそのままapp.xmlに書くのはよくありません。参照している値が変わったときに同期がとれなくなるからです。しかし、どういった項目が必要かの参考にはなります。
classes.jarはplatform.xmlのpackagedDependencyに記載するものです。わかりやすい名前に変更しておいた方が良いでしょう。
/res/はANEの作成ではplatform.xmlのpackagedResourceのfolderNameで指定する物で、パッケージ名と組にして管理する必要があります。わかりやすい名前に変更しておいた方が良いでしょう。中身が空の時も多く、その時はplatform.xmlに記載する必要はありません。
定数や画像などのAndroidのリソースは多言語化、多解像度対応が容易なRクラスを利用するために/res/に入れるのが普通です。しかし、直接ファイルをあつかいたい場合にはリソースを/assets/に入れることがあります。この中にファイルがあれば、それらはANE作成時ではなく、Airアプリ作成時に取り込んでおく必要があります。Animateの「Air for Android設定」の「含めるファイル」の一番上の階層に入れておけば、apkを書き出すとその中に自動的に「assets」というディレクトリが作成されてそこに格納されます。
例えば取り込むaarファイルを展開した/assets/以下に「test.png」というファイルが含まれていたら、以下のようにします。
ライブラリアップデートでANEを作り替えるときは、Airの方での取り込みも修正しないといけないわけです。忘れやすいところですから注意してください。
(This host) = https://njf.jp