web-dev-qa-db-ja.com

アプリが動的にロードするAPKと個別のライブラリを構築する方法

簡単な要約は次のとおりです。APKと個別のライブラリ(JAR、AAR、DEXファイルなどの何らかの形式のクラスのセット(理想的にはリソースも)を意味します)を構築しますが、これらのライブラリをAPK;代わりに、アプリは実行時にそれらをロードしますか?

詳細

したがって、私の主な質問は、そのようなアプリをどのように構築するか(Gradle構成など)です。どのクラスをどのJARまたはDEXファイルに入れるかを指定するにはどうすればよいですか?最終的に使用するDEXファイルごとにAndroid Studioモジュールを作成しますか?

密接に関連する質問は、Javaコードが外部ライブラリをロードし、実行時にそれらのクラスにアクセスする方法です。後者の場合、 アクセスする)に示されているアプローチを期待しています。 classloaderによるdexファイルからアプリのクラスへ は機能します。

https://developer.Android.com/studio/projects/Android-library.html で手順を試しましたが、が実行するAPKがビルドされます依存関係ライブラリを含めます。

Multidex( https://developer.Android.com/studio/build/multidex.html )も試しましたが、開発者がどのクラスに入るのかを制御できないようです。どのDEXファイル、さらにそれらすべてを1つのAPKにパッケージ化します。 AFAICT実行時にこれらのDEXファイルのロードを制御する方法はありません。

バックグラウンド

ここでは「 X-Y問題 」の可能性があるので、背景を説明したほうがいいです。

クライアント向けのアプリを作成しています。アプリストアを通じて配布されることはないため、更新のための通常のメカニズムにアクセスすることはできません。代わりに、クライアントは、新しいAPKを手動でサイドロードする必要なしに、アプリ自体の新しいコンポーネントをダウンロードして古いコンポーネントを置き換えることで、アプリが自分自身を更新できることを望んでいます。ここでの主な動機は、技術者以外のユーザーにとって更新が簡単でなければならないということです。アプリが更新プロセスを制御できる場合、アプリはそれをスムーズにし、ユーザーをガイドすることができます。

さらに、アプリはインターネットアクセスが少なく高価な地域で使用されるため、クライアントは、ユーザーにアプリ全体を再ダウンロードして受信させるのではなく、アプリの更新を小さなチャンク(2MBなど)で発行できるようにしたいと考えています。小さな更新。

重要な場合に言及する必要がある要件の1つの側面は、実行時にロードされるライブラリがmicroSDカード上に存在することになっていることです。これは、インターネットにアクセスせずに更新を配布するのにも役立ちます。

アプリの現在のステータスは、約50%書かれています。つまり、以前のバージョンがいくつかリリースされていますが、上記の要件やその他の要件を満たすために、アプリを変更(再構築)する必要があります。

31
LarsH

このチュートリアルは、DEXファイルを外部からロードするための良いスタートです。ソースの3つの小さなファイル(MainActivity.Java、LibraryInterface.Java、LibraryProvider.Java)のみで、secondary_dex.jarをassetsフォルダーから内部アプリケーションストレージ[outdex/dex]にコピーします(インターネットもチュートリアルで可能な限り説明されています) )。カスタムビルドステップを使用するため、 ant でビルドする必要があります。私はそれを試しました、それはうまくいきます。一見の価値があります。
DalvikおよびARTでのカスタムクラスの読み込み


[〜#〜] update [〜#〜]このコードはAndroidスタジオグラドル(antは不要) https://github.com/timrae/custom-class-loader
テスト済みokcom.example.toastlib.jarSDcardから内部アプリケーションストレージ[outdex/dex]、(アセットフォルダーではありません)。 (プロジェクトをビルドするには、プロジェクト内のREADME.mdファイルを読み取る必要があります)。

Q:アクティビティを追加するにはどうすればよいですか?マニフェストに追加できませんか?
A:フラグメントを使用します。マニフェストにエントリは必要ありません。

Q:既存のプロジェクトに追加することを目的としたリソースを備えたJarは、そのリソースをプロジェクト自体のリソース(R.)とマージできる必要があります。
A:ハックが利用可能です、データファイル...
パッケージ化Android配布可能なJarファイル内のリソースファイル

Q:外部ファイルの権限が間違っています。
A:インポートします。

Q:使用許可を追加する必要があります。
A:API23を使用すると、プログラムで使用許可を追加できます(ただし、マニフェストで宣言する必要があるため、- 新しい権限モデル おそらく私たちにはあまり役に立ちません)。

このセクションは、より一般的なユーザーを対象としています(@LarsHには、更新に関するより具体的な要件があります)。上記の例は、17kbのapkと1kbのjarです。コードの大部分を1回限りのjarに入れることができ、更新には新しいApkをロードするだけです(データ転送を最小限に抑えるために、バルクコードjarをインポートします)。 APKが大きくなりすぎた場合は、小さいAPKからやり直して、すべてを別のjarに移行します(2つのjarをインポートします)。コーディングの労力、ユーザーエクスペリエンス、保守性、サポート性、帯域幅、Androidルール、Playストアルール(これらの単語が存在する場合; O))のバランスを取る必要があります。

注Dalvikは廃止されました

Dalvikの後継はAndroid Runtime(ART)で、同じバイトコードと.dexファイル(.odexファイルは使用しない)を使用します。後継は、エンドユーザーに対して透過的なパフォーマンスの向上を目的としています。新しいランタイム環境は、テクノロジープレビューとしてAndroid 4.4 "KitKat"に初めて含まれ、それ以降のバージョンではDalvikを完全に置き換えました; Android 5.0 " Lollipop」は、ARTが唯一含まれているランタイムである最初のバージョンです。

6
Jon Goodwin

同じ sharedUserId と同じ process で複数のapkを構築しようとすることができます。

これは Threema によって使用されるプラグインメカニズムです

編集:Theemaの詳細

Threemaには1つのメインアプリと2つのプラグインがあります。

そうすることで、メインアプリはカメラやマイクにアクセスするための権限を必要としません

1
larsgrefer