Unity解決報錯“Too many field references: xxx; max is 65536”(超過64K)

前言

需要分Dex的理由想必大家都知道了.正是在ART以前的Android系統中,Dex文件對於方法索引是用一個short類型的數據來存放的.而short的最大值是65535,因此當項目足夠大包含方法數目足夠多超過了65535(包括引用的外部Lib裏面的所有方法),當運行App,就會得到如下的錯誤提示.

Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

 

這個致命嚴重的Bug出現後,Android官方就寫了一篇著名的Blog(這篇文章我讀了五六遍,甚至連作者的Google+的照片我都看了兩三次,我還是沒有完全搞明白怎麼Walkaround這個嚴重的問題).

再後來,慢慢發展,有很多能人異士發揮自己的創造力,寫了開源的Lib放在GitHub上分享給其他Android開發者們使用.HelloMultiDexSecondary-Dex-Gradle等等.

但是解鈴還須繫鈴人,這種系統性的嚴重致命Bug,當然還是Android官方給出解決方案最讓人放心.終於,我們還是等到了你,MultiDex Offical Solution.

我推薦官方文檔這篇GitHub的文章一起看會有更好的瞭解,少走彎路.

 

Unity隨着sdk的接入,Jar包越來越大,包內方法數超過64K的時候會打包失敗,保以下錯誤:

“Too many field references: xxx; max is 65536”

依照官方文檔有兩種解決方式

1:修改Unity Android相關數據,使Unity支持MultiDex

2:導出AS工程,在AS中支持MultiDex

依照Unity的開發習慣,我們選擇前者

具體做法如下

1、打開目錄[UnityInstallationDirecory]\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\GradleTemplates, 拷貝 mainTemplate.gradle文件到[ProjectName]\Assets\Plugins\Android目錄。 
2、 打開目錄 [UnityInstallationDirecory]\Editor\Data\PlaybackEngines\AndroidPlayer\Apk, 拷貝AndroidManifest.xml文件到[ProjectName]\Assets\Plugins\Android目錄。如果該目錄已有AndroidManifest.xml文件,重命名爲AndroidManifest1.xml。 
3、 修改mainTemplate.gradle爲:
添加兩行命令,在文中位置已標記好

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}

allprojects {
   repositories {
      flatDir {
        dirs 'libs'
      }
   }
}

apply plugin: 'com.android.application'

dependencies {
    compile 'com.android.support:multidex:1.0.1'    //在該行加入
    compile fileTree(dir: 'libs', include: ['*.jar'])
**DEPS**}

android {
    compileSdkVersion **APIVERSION**
    buildToolsVersion '**BUILDTOOLS**'

    defaultConfig {
        multiDexEnabled true    //在該行加入
        targetSdkVersion **TARGETSDKVERSION**
        applicationId '**APPLICATIONID**'
    }

    lintOptions {
        abortOnError false
    }
**SIGN**
    buildTypes {
        debug {
            jniDebuggable true
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
            **SIGNCONFIG**
        }
    }

    dexOptions {
    javaMaxHeapSize "4g"
    }

}

4、 修改AndroidManifest.xml爲:

複製粘貼即可

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="1.0">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>

    <application
        android:theme="@style/UnityThemeSelector"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:name="android.support.multidex.MultiDexApplication">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>

5、將所有AndroidManifest的[android:debuggable=”true”]項移除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章