くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

MultiDexを利用して、正しくUNEXPECTED TOP-LEVEL EXCEPTIONに対処する

前の記事で、本当の原因がわからず解決していた(UNEXPECTED TOP-LEVEL EXCEPTION)について、正しい解決策が紹介されていた。

その備忘録。というか引用。

本当の原因

本当の原因は、apkに含まれるメソッドの数が多すぎることらしい。

apkに含められるメソッドの総数は65,535が上限で、サポートライブラリなどを含めるとすぐに到達してしまう。

Lolipopでは対策が取られていて問題ないようだが、それ以前の4.x系以下で起こるらしい。

この問題を解決するサポートライブラリとして、multidex support libが公開されているので、 基本的にはそれを利用すればOK。

やったこと:multidex support lib を使う

build.gradleの設定

multidexライブラリを使うようにbuild.gradleを設定。

apply plugin: 'com.android.library'

android {
    compileSdkVersion 20
    buildToolsVersion '21.1.2'

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 20
        ・・・
        //multiDexを有効にする
        multiDexEnabled true 
    }
    dexOptions {
        //最大ヒープサイズを4Gに設定
        javaMaxHeapSize "4g"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    ・・・
    // support libを依存関係に含める
    compile 'com.android.support:multidex:1.0.0'
}

こんな感じに設定。

注意点としては、ヒープサイズも設定すること。

multiDexにするとメモリを食うので、多めに設定。自分の環境の場合、デフォルトでは失敗してしまいました。

MultiDexApplicationを適用

muiltDexを利用する場合は、特別なMultiDexApplicationを利用する必要があるので、AndroidManifest.xmlに設定。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="..."
    android:installLocation="auto">

    ・・・

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="android.support.multidex.MultiDexApplication">
        <activity
            android:name=".MyActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

独自のApplicationを利用している場合には、以下な感じで、MultiDexApplicationを継承してattachBaseContextメソッドをオーバーライトすればOK

public class MyApplication extends MultiDexApplication {
    ・・・
    
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

以上!!

[PR] めもらばではこんなあぷりを作っています!

参考にしたサイト様