Android导出Activity到AAR包供Unity使用

想在 Unity 中显示 Android 界面,但又不想导出 Unity 工程在 Android Studio 里编辑,于是探索将 Activity 导出到 AAR 包,用 Unity 编译打包的方法。

说明

本文介绍了通过 Unity Editor 打包含 Android Activity 在内的多 Activity 应用的方法,至于多 Activity 的使用因人而异,仅简单探讨,后续在其他文章详细讨论。

一般情况下,Unity 应用对其他 Activity 有两种用途:

  • Activity 画面渲在一张纹理上,在 Unity 3D 场景内显示为一个片;
  • 直接跳转 Activity,退出 Unity Activity。

前者够写好几篇文章的,而后者简单到根本不用写,因此本文不会探讨具体用法。

所以,让我们开始吧~

准备额外的 Activity

在 Android Studio 中创建一个 Module:

在 Module 中创建一个 Activity,按需拼好界面,写好 Activity 逻辑:

用于 Unity C# 层的拉起 Activity 方法

这里只提供拉起 Activity 的 Intent 构建方法。

public void unityCallStartActivity(){
    Intent intent = new Intent(this.unityActivity, testActivity.class);
    /*
    在 VirtualDisplay 上展示
    ActivityOptions activityOptions = ActivityOptions.makeBasic();
    activityOptions.setLaunchDisplayId(this.targetVirtualDisplayId);
    this.unityActivity.startActivity(intent, options.toBundle());
    */
    this.unityActivity.startActivity(intent);
}

至于如何在 Unity 里调用上述 Java Android 方法,应该没人不会,略。

给 Activity 添加 Theme

上文创建的 Activity 没有默认 Theme,Unity 里拉起 Activity 时会报错。

我们需要在AndroidManifest.xml里给 Activity 添加一个 Theme:

<activity
    android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
    android:name=".testActivity"
    android:exported="false" />

本处仅为示例,具体 Theme 和需求有关:例如是不是需要 ActionBar 等。

导出 AAR 包

选中当前 Module,在 Android Studio 菜单栏选择Build/Make Module:

稍等片刻,可以看到生成的 aar 包:

Unity 打包配置修改

Unity 本质也是 Gradle 打包,只不过把大部分可配置项都隐藏了。

Player Setting 中勾选如下两项:

  • Custom Launcher Gradle Template
  • Custom Gradle Properties Template

勾选后,Unity 将把默认的 Gradle 配置文件拷贝到Plugins/Android中供你修改:

1. 开启 AndroidX 支持

gradleTemplate.properties中添加:

android.useAndroidX=true
android.enableJetifier=true

改完记得保存。

2. 添加 module 依赖

我们需要在launcherTemplate.gradle中加入 Module 的依赖包。

上文打包的 AAR 的不包含 dependencies,有人认为这是坏事,会用各种 bypass 手段让 AAR 打入依赖的包,我不推荐这么做。模块不包含依赖包是好事:如果多个 AAR 都依赖同一个包,且各自都包含一份该依赖,打包会冲突的。

通常把 Module 文件夹中build.gradle文件内dependencies下的implementation拷贝过来即可:

# 一个例子,不要直接拷贝本文
implementation 'androidx.appcompat:appcompat:xxx'
implementation 'com.google.android.material:material:xxx'
implementation 'androidx.constraintlayout:constraintlayout:xxx'

当然,这里有坑,后面疑难解答里会详细说。

3. 拷贝 AAR

将上文中生成的 AAR 文件放置在Plugins/Android中。

打包

现在就可以去打包了(大概率打包会报错,见后文疑难解答)。

如果得法,你将通过 Unity Editor 附带的编译工具打出一个多 Activity 应用出来,比如我这个:

至于如何使用其他的 Activity,就看个人需求了,不过使用范围应该都在前文提到的“两种用法”范围内。

疑难解答

问题1:打包报错 uses-sdk:minSdkVersion xx cannot be smaller than version xx declared in library

我们的 Module 有MinSdkVersionTargetSdkVersion设置,可以在module settings中管理:

这个报错是因为 Unity 的Minimum API Level低于 module 的MinSdkVersion,此时有两种解决方法:

  • 降低 module 的MinSdkVersion,重新出 aar 包;
  • 提高 Unity 的Minimum API Level

问题2:打包报错 AAPT: error: resource android:attr/lStar not found.

这就是上文提到的坑点。

Android 这边对compileSdkVersionTargetVersion是有区分的:

  • compileSdkVersion是应用编译时需要的 SDK 版本;
  • TargetVersion是应用运行时的版本。

一个库如果即兼容低版本又适配高版本的新特性,则需要用高版本编译,原则上compileSdkVersion >= TargetVersion即可。

Unity 把Target API Level作为打包的compileSdkVersion,一般来说,这种做法是没问题的。

但是,当你的Target API Level比 dependencies 的compileSdkVersion低时,就出问题了。

以本问题为例,编译时的依赖顺序:

  • 当 appcompat 版本较高时编译
    • ↑ 编译依赖新版的 AndroidX 组件
      • ↑ 编译依赖 android:attr/lStar,Android 12 才有
        • ↑ 要求 compileSdkVersion ≥ 31

对这个问题有两种解决方法(以及一种和本文无关的方法):

  • 提高 Unity Target API Level到 API 31,同时保持minimum API Level不变(兼容低版本设备);
  • 使用低版本的 dependencies 包。
  • (非本文情况)导出工程,用 Android Studio 修改compileSdkVersion后打包。

如果不想修改Target API Level到 Android 12,执意使用低版本的 dependencies,下面的版本是一个推荐值:

implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

至于其他包的依赖关系,可以在 https://mvnrepository.com/ 里查看。

梓喵出没博客(azimiao.com)版权所有,转载请注明链接:https://www.azimiao.com/9512.html
欢迎加入梓喵出没博客交流群:313732000

我来吐槽

*

*

0位绅士参与评论

  1. 离殇05-17 10:32 回复

    不考虑在站点上加上RSS吗