アプリケーションをBox、Dropbox、Googleドライブと統合しようとしています。これら3つのサービスはすべて、いくつかのサードパーティのjarファイルを必要とします。さらに、私のアプリケーションにはすでにいくつかのサードパーティのjarが必要です。 Eclipseからアプリケーションを実行しようとすると、次のエラーが発生します。
Dexを実行できません:[0、0xffff]にないメソッドID:65536 Dalvik形式への変換に失敗しました:dexを実行できません:[0、0xffff]にないメソッドID:65536
このエラーは、アプリケーションにメソッドが多すぎるために発生しているようです。私はこれらのメソッドの大部分がサードパーティのjarからのものであることをかなり確信しているので、コードを単純化することによってこれを解決しようとすることは非現実的です。これら2つの提案をオンラインで見つけました。
追加 dex.force.jumbo=true
to project.properties(およびadtバージョン21を使用)。私はこれを行いましたが、それでもエラーが発生します。
ここで説明するように、複数のdexファイルを使用します: http://Android-developers.blogspot.co.il/2011/07/custom-class-loading-in-dalvik.html 。これが唯一のオプションのようですが、私の場合にどのように適用されるのかわかりません。問題は、ドライブなどのサービスの依存関係が多すぎることです。このソリューションでは、依存関係を参照するときに、語形変化を使用するようにドライブソースを変更する必要がありますか? (これは明らかにオプションではありません)。
プロガードを使用して、未使用のコード/メソッドを縮小削除します。 proguardを使用したアプリケーションのエクスポートは機能し、ドキュメントサービスの統合は、4.0以上のデバイスで期待どおりに機能します。ただし、2.3デバイスでテストすると、classnotfoundエラーがスローされます。
だから、私はこの問題についてのアドバイスを期待しています。オプション2は私のケースの解決策ですか?考慮すべき別の解決策はありますか?
これらの1つ以上を、ダウンロード可能な個別のAPKの形式で、メインアプリへのプラグインとして開発することもできます。そのAPKは、メインアプリが使用するいくつかのコンポーネントを公開します。これらのサービスとの統合の性質がわからないため、それについてより具体的な推奨を行うことはできません。独自のsignature
レベルのカスタム<permission>
を使用して、2つのアプリ間の通信を保護します。さらに、おまけとして、サードパーティライブラリを使用して追加の権限の要件を追加する場合、メインのAPKを小さく保ちながら、プラグインAPKでそれらの権限のみが必要になります。
Multi-dexサポートは自動的に含まれます。 ドキュメントから:
Android 5.0以降では、ARTと呼ばれるランタイムを使用しています。このランタイムは、アプリケーションAPKファイルから複数のdexファイルの読み込みをネイティブでサポートしています。 ARTは、クラス(..N).dexファイルをスキャンしてAndroidデバイスで実行するために単一の.oatファイルにコンパイルする)アプリケーションのインストール時にプリコンパイルを実行します。詳細については、 Android 5.0ランタイム、ARTの紹介をご覧ください。
Android mult-dex support tool to your gradle build: を追加するだけです
Android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.Android.support:multidex:1.0.0'
}
Dalvik VMは、バイトコード命令セットが16ビット以上を必要とするメソッド番号を参照する方法を持たないため、dexファイルごとに最大65536のメソッドを持つことができます(@danfuzzによって指摘されたように)コメントで)。
複数のdexファイルを使用してこれを修正することは可能ですが、Facebook 別の修正が見つかりました アプリ内で展開して問題を回避できます。
Vm/LinearAlloc.cを参照してください。このコードを見つけることができます:(Android 2.3.3の下に5MiB、Android 4.0)の後に8MiB)
#define DEFAULT_MAX_LENGTH(5 * 1024 * 1024)
...
LinearAllocHdr * pHdr;
...
pHdr-> mapLength = DEFAULT_MAX_LENGTH;
「Facebookフィックス」がネイティブCポインターを使用してこのメモリを編集していると思います。 IMHO LinearAlloc問題とこのメソッドID問題は異なります。
最近この問題に直面しました。より詳細な実装についてWebを調査した後、私はそこに他に多くはないことに気づきました:
問題はコードにメソッドが多すぎることではなく、コードと他のライブラリの完全なdex
が問題であることに気付きました。したがって、ライブラリに対してコードをコンパイルできても、それらをclasses.dex
に含めずに、ライブラリを個別にdex
し、実行時にすべてをまとめると、動作するはずです。取り残された唯一の問題は、クラスローダーです。
少しリフレクションといくつかのGroovyコードを使用して、ライブラリとアプリケーションコードを別々のdex
ファイルにパッケージ化する比較的安定した方法を思いついたと思います。
65kメソッドの制限に達した場合の問題のほとんどは、アプリでのマストドンティックGoogle Playサービスの使用に関連しています。最近、それを使用すると、より細かい設定を取得できます。
このガイド に続いて、必要な部分だけを使用できます。おそらくこれで問題が解決し、いくつかの黒魔術を回避したり、multiDexを使用したりできます。たとえば、アプリでGoogleマップのみが必要な場合(広告、ウォレット、Google Wear、アナリティクスなどを使用していない場合)、依存関係全体を使用することは時間/スペースの無駄になります。あなたはそれをそのように使うことができます:
compile com.google.Android.gms:play-services-base:6.5.87
compile com.google.Android.gms:play-services-maps:6.5.87
「パーツ」の全リストは this link で読むことができます
そのためにDexサポートを有効にする必要があります。したがって、次の手順を実行する必要があります。
Android { defaultConfig { ... multiDexEnabled = true } }
dependencies { ... compile 'com.Android.support:multidex:1.0.0' }
A.マニフェストマニフェストにMultiDexApplicationを追加する
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.Android.multidex.App"> <application
Android:name="Android.support.multidex.MultiDexApplication">
</application>
</manifest>
B. MultiDexApplicationによってアプリケーションを拡張する
public class App extends MultiDexApplication { .. }
C.ベースコンテキストをアタッチしてアプリケーションにインストールします。
public class App {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
..
}
}
詳細については、このリンク MultiDex を参照してください。
ここ は、特定のフォルダーの各jar(および合計)のメソッド数をカウントするために私が作成したスクリプトです。
メソッドを数えたら、重いライブラリのリファクタリングと削除に集中できます。