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”]项移除。

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