Gradleを使用して64kメソッドの制限を解決するproper/easy
の方法はありますか?
つまり、単一のclasses.dex
の代わりに、事前に定義されたjarを使用して個別のdexファイルを作成するカスタムGradleタスクを意味します。
ありがとうございました
イワン
現在、私はGMSと格闘中です。GMSはAnalyticsを使用するための2万の方法を取り入れています。私はProguardを使用して不要なものを取り除きますが、それでも... 72kのメソッドとカウント...
dx
パラメータ-multi-dexを使用して、classes.dex
を2つのファイルに分割できます。手動編集で実現しました
sdk/build-tools/Android-4.4W/dx
そしてこのように最後の行を編集します:
exec Java $javaOpts -jar "$jarpath" --multi-dex "$@"
APKファイルに__classes.dex__ and __classes2.dex__
が含まれるようになりました。
私はいくつかの方法で2番目のファイルを動的にロードしようとしています:
残念ながら、まだ運がありません。 Google/Facebook/Squareの第一人者が適切な解決策を提供できることを本当に望んでいます。
Android Gradleプラグイン2.2.0の更新:dex
タスクにアクセスできませんもう、しかし代わりにadditionalParameters
がdexOptions
の一部として導入されました。
Android {
dexOptions {
additionalParameters += '--minimal-main-dex'
// additionalParameters += '--main-dex-list=$projectDir/<filename>'.toString()
// additionalParameters += '--set-max-idx-number=55000'
}
}
Android Gradleプラグイン0.14.0の更新:新しいmultiDexEnabled true
ディレクティブを介した直接マルチdexサポート( build-tools 21.1.0、サポートリポジトリリビジョン8、およびAndroid Studio 0.9)が必要です。
元の回答:Gradle Androidプラグイン0.9.0以降、実際にはできますこれをアプリの--multi-dex
ファイルに追加して、build.gradle
をdx
に渡します。
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = ['--multi-dex']
} else {
dx.additionalParameters += '--multi-dex'
}
// Add more additional parameters like this:
dx.additionalParameters += '--main-dex-list=class-list.txt'
dx.additionalParameters += '--minimal-main-dex'
}
}
これまでのところ、作成については、複数のdexファイルがあります。複数のdexファイルを実際に使用するには、 https://github.com/casidiablo/multidex (これはGoogleの今後のフォークです)を見てください。 MultiDexサポートライブラリ)。
Gmsが問題で、gradleを使用している場合
Gmsバージョン6.5以降、個々のAPIライブラリを選択できます
たとえば、MapsAPIのみを含めるには:
compile 'com.google.Android.gms:play-services-maps:6.5.87'
そしてここに完全なリストがあります:
com.google.Android.gms:play-services-base:6.5.87
com.google.Android.gms:play-services-ads:6.5.87
com.google.Android.gms:play-services-appindexing:6.5.87
com.google.Android.gms:play-services-maps:6.5.87
com.google.Android.gms:play-services-location:6.5.87
com.google.Android.gms:play-services-fitness:6.5.87
com.google.Android.gms:play-services-panorama:6.5.87
com.google.Android.gms:play-services-drive:6.5.87
com.google.Android.gms:play-services-games:6.5.87
com.google.Android.gms:play-services-wallet:6.5.87
com.google.Android.gms:play-services-identity:6.5.87
com.google.Android.gms:play-services-cast:6.5.87
com.google.Android.gms:play-services-plus:6.5.87
com.google.Android.gms:play-services-appstate:6.5.87
com.google.Android.gms:play-services-wearable:6.5.87
com.google.Android.gms:play-services-all-wear:6.5.87
さまざまなdexファイルを分割してロードするプロジェクトの例は次の場所にあります。
https://code.google.com/p/Android-custom-class-loading-sample/
編集:Gradleについてはすでに答えがあります
私は https://github.com/creativepsyco/secondary-dex-gradle/ のメンテナーであり、gradle n00bなので、BASHスクリプトのパスを選択しましたが、実行できると思います。ビルドファイルに直接。 ORプラグインとして実行するようにリファクタリングすることができますが、Gradleに慣れ親しんでいるときにそうするかもしれません。これが私のロジックの理由です。
DEXを分割する方法を理解するには、ビルドシステムのタスク順序を知っている必要があります。 gradleを使用している場合は、ビルドサイクル内に一連のタスクが挿入されていることを知っておく必要があります。
例えば:
:sdk:processReleaseJavaRes UP-TO-DATE
:sdk:packageReleaseJar
:sdk:compileReleaseNdk UP-TO-DATE
:sdk:packageReleaseJniLibs UP-TO-DATE
:sdk:packageReleaseLocalJar UP-TO-DATE
:sdk:packageReleaseRenderscript UP-TO-DATE
:sdk:packageReleaseResources UP-TO-DATE
:sdk:bundleRelease
:app:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:app:prepareComFacebookAndroidFacebook3141Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJava
:app:preDexDebug
:app:dexDebug
:app:processDebugJavaRes UP-TO-DATE
:app:validateReleaseConfigSigning
:app:packageDebug
:app:zipalignDebug
:app:assembleDebug
Dexingを実行するには、dex *タスクとprocess *タスクの間にカスタムタスクを挿入できる必要があります。これができれば、Multiple DEXingが簡単になります。
Bashスクリプト here は基本的にこれを実行します。デバッグタスクを調べると、基本的に次のようになります。
exploded-aar
フォルダーに存在し、DEXツールを実行します // For Debug simply remove the library from getting dex and create it
//----------------------- Extra Debug Step ----------------//
def libraryFiles = new ArrayList<?>()
def secondaryFile = new ArrayList<?>()
variant.dex.libraries.each {
File file ->
if (!file.absolutePath.contains("lib/unspecified/classes.jar")) {
libraryFiles.add(file)
} else {
secondaryFile.add(file)
}
}
variant.dex.libraries = libraryFiles
//----------------------- Extra Debug Step ----------------//
packagingTask.dependsOn variant.javaCompile
}
これは手動でライブラリをdexedから削除し、bashスクリプトを介して生成できるようにします。
リリースプロセス中のデキシングも同じように理解できると思います。注意すべき他の重要なことは、ProguardタスクがAndroid gradleプラグインによって制御されており、それについてあまり変更できないことです。Proguardルールの問題:
他の重要なコードチャンクは SecondaryDex.Java にあり、これは基本的に2番目のdexファイルをロードし、DEXファイルのパスをランタイムクラスパスに挿入します。これを最適化して、アプリが再開されるたびにDEXファイルを読み取る代わりに、パスを挿入するだけで済みます。
Google Play開発者サービス(20Kメソッドを追加)で2番目のDex実験を行い、別のDEXファイルに分離することができました。このようにして、私のメインのdexファイルはGooglePlay開発者サービスの肥大化の影響を受けません。
Gradleタスクサイクルがどのように機能するかを理解するには、 BasePlugin.groovy ソースを参照してください。バリアントオブジェクトにアクセスしてタスクをビルドするための適切なAPIが存在するまで、一部の側面を制御するのが難しいことがわかります。 。