背景&问题&目的

  • 背景:老项目一直是用Unity5.6.3f1默认Internal打包方式,结合Jenkins构建的。新项目使用2018.4.2f1构建
  • 问题:项目接入小米最新版本SDK时,接入的Jar包很多,遇到了方法数超过 64K的问题,使用Unity的Innternal打包方式无法成功打包;如果选择用Export Gradle Project方式,自动化流程改动较大;只能选择使用Unity Gradle方式打包。
  • 记录Unity5.6.3f1使用Unity Gradle打包的流程和解决遇到的问题。

步骤

  • 新建Unity空工程(测试时建议使用小工程测试),导入项目中使用到的Plugins/Android目录内容,同时导入小米SDK资源,Build Settings中Build System选择Gradle。
  • 从Unity5.6.3f1安装目录“Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\GradleTemplates”,获取到mainTemplate.gradle 和 libTemplate.gradle两个文件,复制到上面新建的工程里
  • 修改mainTemplate.gradle,在 buildscript/repositories 和 allprojects/repositories 对象内添加
repositories {
maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
//注意保留原来的内容
...
}
  • 修改mainTemplate.gradle和libTemplate.gradle,修改 buildscript/dependencies 对象中的 classpath 'com.android.tools.build:gradle:2.1.0' 的gradle版本号为2.3.3
 dependencies {
  classpath 'com.android.tools.build:gradle:2.3.3'
 }
  • 修改mainTemplate.gradle, 在 dependencies 对象中添加
dependencies {
//注意保留原来的内容
...
 compile 'com.android.support:multidex:1.0.3'
}

在 android/defaultConfig 对象中添加

android {
 defaultConfig {
//注意保留原来的内容
...
  multiDexEnabled true
 }
}
  • 更新Unity 5.6.3f1中的Gradle版本
* Unity 5.6.3f1中集成的Gradle版本是 2.1.0
* Unity 2018.4.2f1集成的Gradle版本是 4.6.0
分别本地安装的找到Unity 5.6.3f1和Unity 2018.x的安装目录“Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle”中的lib文件,先备份5.6.3f1的lib文件,再将2018.x的lib复制过来。
  • Jenkins工程配置:在Unity player settings中配置安卓签名
//例如
PlayerSettings.Android.keystoreName = KeystorePath;
PlayerSettings.Android.keyaliasName = "alias";
PlayerSettings.Android.keyaliasPass = "123456";
PlayerSettings.Android.keystorePass = "123456"; 
  • Jenkins工程配置:在Unity player settings中配置BundleId
//例如
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, BundleName);
  • Jenkins工程配置:在Unity build settings中选择Gradle
//例如
 EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
  • 整合小米SDK提供的Jar包
使用ANT整合打包小米提供的Jar  (命名格式:support-xxx-27.1.1.jar)
和工程内现有的android-support-v4.jar进行对比
删除从小米导出的Jar里的对比相同的类 (尽量保证工程内现有使用android-support-v4.jar的功能稳定,只增加一个小米的不稳定因素)
尝试打包

问题&解决

  • 测试时如果遇到打包失败时,下一次尝试打包时,记得删除Unity 工程目录下的Temp目录
  • 没有开代理的情况下,遇到无法获取gradle的问题
摘自下文参考链接中的类似日志
* What went wrong:
A problem occurred configuring root project 'gradleOut'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:2.1.0.
     Required by:
         project :
      > Could not resolve com.android.tools.build:gradle:2.1.0.
         > Could not get resource 'https://jcenter.bintray.com/com/android/tools/build/gradle/2.1.0/gradle-2.1.0.pom'.
            > Could not HEAD 'https://jcenter.bintray.com/com/android/tools/build/gradle/2.1.0/gradle-2.1.0.pom'.
               > Connect to XXX [/XXX] failed: Connection refused: connect
    * 解决方法:
    配置阿里云国内镜像
  • 在默认使用Unity5.6.3f的gradle版本执行打包时
* What went wrong:
A problem occurred evaluating root project 'gradleOut'.
> Failed to apply plugin [id 'com.android.application']
   > Gradle version 2.10 is required. Current version is 4.0.1. If using the gradle wrapper, try editing the distributionUrl in E:\Unity3D\TTAiLaoyu\Temp\gradleOut\gradle\wrapper\gradle-wrapper.properties to gradle-2.10-all.zip
    * 解决方法:
拷贝2018版本的Unity的gradle到5.6.3f1下,并修改.gradle文件的gradle版本号2.3.3
如果使用AndroidStudio,方法一样,也是更新最新的gradle解决这个问题的版本
如:使用最新的AndroidStudio3.0
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
    注:如果使用的是AndroidStudio2.3或更低版本,请使用
classpath 'com.android.tools.build:gradle:2.3.3'
  • 遇到jar包类重复:
duplicate entry: com/bumptech/glide/gifdecoder/GifDecoder$BitmapProvider.class 类似日志
    解决方法:尝试删除新导入jar包中的同包名+类名的类文件
  • 针对多 dex 文件配置您的应用:
当 minSdkVersion 低于20及以下时,注意配置三点
android {
        defaultConfig {
            ...
            minSdkVersion 15
            targetSdkVersion 28
           // 1
             multiDexEnabled true
        }
        ...
    }
    dependencies {
           // 2
      compile 'com.android.support:multidex:1.0.3'
    }

    // 3
不替换Application
  <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp">
        <application
                android:name="android.support.multidex.MultiDexApplication" >
            ...
        </application>
    </manifest>
替换Application
 public class MyApplication extends MultiDexApplication { ... }
替换Application 但无法修改基类
public class MyApplication extends SomeOtherApplication {
      @Override
      protected void attachBaseContext(Context base) {
         super.attachBaseContext(base);
         MultiDex.install(this);
      }
    }

总结&后续

  • Unity打包的报错信息,仔细查找定位问题核心,根据不同问题,找对应的解决方法;对于Gradle的语法和一些常用问题需要记录和整理。
  • 多 dex 文件支持库具有一些已知的局限性,将其纳入您的应用编译配置时,您应注意这些局限性并进行针对性的测试:
启动期间在设备的数据分区上安装 DEX 文件的过程相当复杂,如果辅助 DEX 文件较大,可能会导致应用无响应 (ANR) 错误。在这种情况下,您应通过 ProGuard 应用代码压缩,以尽量减小 DEX 文件的大小,并移除未使用的那部分代码。
当运行的版本低于 Android 5.0(API 级别 21)时,使用多 dex 文件不足以避开 linearalloc 限制(问题 78035)。此上限在 Android 4.0(API 级别 14)中有所提高,但这并未完全解决该问题。在低于 Android 4.0 的版本中,您可能会在达到 DEX 索引限制之前达到 linearalloc 限制。因此,如果您的目标 API 级别低于 14,请在这些版本的平台上进行全面测试,因为您的应用可能会在启动时或加载特定类组时出现问题。

参考&感谢

01-02 04:27