動的クラスローディングでAndroidアプリ“裏”開発:Androidで動く携帯Javaアプリ作成入門(40)(1/3 ページ)
アプリ実行時の可能性を拡げるClassLoaderの使い方をサンプルとともに解説。JARをDEXに変換する方法や4つの注意点も。
動的クラスローディングで何ができる?
Javaでは、起動時のみでなく、実行時にユーザープログラムの制御によって、外部リソースからクラスを読み込み、メソッドを実行できます。そうです、ClassLoaderを使用して外部からクラスを読み込めばよいのです。
動的クラスローディングが行えることで、どのようなメリットがあるでしょうか。
- ゲームのステージなど、必要なリソースを後から追加。必要なくなったリソースは削除
- ユーザープラグインのような仕組みが導入可能
- データやプログラムの配信・修正が容易になる
Androidでは、動的クラスローディングはJavaのそれとは少し事情が異なります。今回は、その事情や対応方法を詳しく解説していきます。
読み終えた段階で、ほぼ満足いく形で動的クラスローディングが行えると理解してもらうことができるでしょう。
今回のサンプル
今回のサンプルは以下よりダウンロードしてください。
「Hello.zip」は動的にロードするJARファイルが含まれています。今回のサンプルは、「/sdcard」直下にこれらのファイルが存在する前提なので、Hello.zipを展開したフォルダで、エミュレータもしくは実機をUSB接続した状態で以下のコマンドをたたいてください。
adb push Hello_dex.jar /sdcard/Hello_dex.jar adb push Hello.jar /sdcard/Hello.jar
Hello.jarは通常のJavaのJARファイル、Hello_dex.jarがDEX形式のJARファイルです。
今回のサンプルの画面イメージです。
上から5つのボタンは、それぞれ異なる方法で動的クラスローディングを行います。「Convert」というボタンは、通常のJavaのJARファイルを、AndroidのDEX形式のJARファイルに変換します。「Hello!!!」というメッセージは、動的クラスローディングの末呼び出されたメソッドが返した文字列です。Clearボタンはメッセージを消して、Convertで変換されていれば、動的ローディングするJARをデフォルトのものに戻します。
AndroidのURLClassLoaderの事情
Javaには「java.net.URLClassLoader」というクラスが存在します。Javaの場合、システムクラスローダはURLClassLoaderのサブクラスになっています(そのような決まりはないのですが、オラクルの実装を含め、多くのJava VMがそのような実装になっています)。
一方、AndroidのDalvik VMは、システムクラスローダはURLClassLoaderではないばかりか、URLClassLoaderではクラスローディングできないように制限されています。一体なぜでしょうか。
Dalvik VMはJavaのクラスファイルフォーマットを使用せず、独自のDEXフォーマットを採用しているため、クラスファイルが含まれたJARファイルを指定されても、クラスファイルが存在するディレクトリを指定されても対応できません。
また、「URLClassLoader#addURL(URL)」で既存のクラスローダに後からリソースを追加されることも、セキュリティ上防がなくてはなりません。
では、Dalvik VMのシステムクラスローダは、いったいどのようなクラスなのでしょうか。それが、今回解説するdalvik.systemパッケージに含まれるPathClassLoaderです。
dalvik.systemには、4つのクラスが存在します。
クラス名 | 概要 |
---|---|
BaseDexClassLoader | DEXファイルの基本的な実装がされているクラスローダ |
DexClassLoader | .jarや.apkからclasses.dexを読み込むクラスローダ |
PathClassLoader | パスを指定してクラスを読み込むクラスローダ |
DexFile | 上記クラスローダ内で使用されているDEXファイルを表すクラス |
結論を先に言ってしまうと、PathClassLoaderはアプリからの動的クラスローディングには使えません。その理由は後述します。
Copyright © ITmedia, Inc. All Rights Reserved.