目录
前言
一、【环境配置】
1.【配置JDK】
(1)JDK下载
(2)JDK安装
(3)JDK环境配置
(4)检查安装是否成功
(5)JRE配置
2.【配置Gradle】
(1)确认Gradle版本
(2)Gradle下载
(3)Gradle安装
(4)Gradle环境配置
(5)检查安装是否成功
3.【编写打包AAR脚本】
(1)项目工程切换到安卓平台,以代码形式进行打包操作
(2)结合上面代码内容,配置批处理文件
(3)报错记录
(4)解决方式(确认Gradle版本)
4.Untiy 关于 Android 配置资料
(1)Unity打包安卓工程后,根目录下build.gradle文件,里面的依赖项描述
(2)自己安装的Gradle版本,需要兼容之前在Unity安装时候附带的Gradle版本
(3)查找Unity安装时附带的Gradle版本
*(4)自定义修改配置项
前言
之前很多年一直都是Unity发布到PC、Web端,这次需要发布到Android平台,得嘞,开始不断的探坑,首先就从打包发布AAR包开始
一、【环境配置】
1.【配置JDK】
(1)JDK下载
首先登录官网 - Java Downloads | Oracle,下载JDK
版本要求:
(2)JDK安装
下载之后进行安装,直接一键下一步,我选择的是默认C盘作为安装路径
(3)JDK环境配置
安装完之后配置环境变量(如下图所示)
为之后可能其他的配置考虑,这里新建变量名为 JAVA_HOME
(4)检查安装是否成功
配置后检查jdk是否安装成功,cmd命令行输入 java -version,出现下面的提示信息,则说明JDK安装成功
(5)JRE配置
了解得知安装JDK会包含JRE,但是个人安装完JDK之后,在其路径下并未发现JRE,后面如果需要JRE的环境配置,会继续在本文档中进行更新,JRE下载地址:https://www.java.com/zh-CN/download/,安装以及配置方式类似于JDK
2.【配置Gradle】
(1)确认Gradle版本
需要查看Unity 中【安卓Gradle插件版本】,结合【Gradle】和【Andorid Gradle Plugin】的兼容性,最后确认Gradle的版本最低为6.7.1,
但是使用7.0及以上版本打包AAR时会发生报错,暂未查明原因,所以当前不做配置修改情况下,使用Gradle版本为6.7.1-6.9.3 !
(2)Gradle下载
首先登录官网:https://gradle.org/releases/,下载Gradle
(3)Gradle安装
将下载的压缩包进行解压,建议解压目录只包含英文路径,这里我解压到了D盘
(4)Gradle环境配置
(5)检查安装是否成功
配置后检查jdk是否安装成功,cmd命令行输入 gradle -v,出现下面的提示信息,则说明JDK安装成功
3.【编写打包AAR脚本】
(1)项目工程切换到安卓平台,以代码形式进行打包操作
包含了3种打包模式:1.一键打包AAR,2.打包成安卓工程,3.把已经打包好的安卓工程打包成AAR
(具体代码内容如下,具体的输出路径可以具体情况进行修改)
public class Editor_BuildAndorid
{
private static string BulidTime { get => DateTime.Now.ToString("yyyyMMdd"); }
private static Dictionary<string, string> andoridFiles;
private static List<string> androidNeedUpdateFile = new List<string>() { "build.gradle", "AndroidManifest.xml" };
private static string path_Output = "/Output/" + BulidTime;
[MenuItem("工具箱/打包/一键生成AAR")]
public static void OneKeyExportAAR()
{
if (BuildAndroidStudioProject())
BuildAAR();
}
[MenuItem("工具箱/打包/1. 导出Android Studio工程")]
public static void ExportAndroidStudioProject()
{
BuildAndroidStudioProject();
}
[MenuItem("工具箱/打包/2. 将Android Studio工程生成AAR")]
public static void ExportAAR()
{
BuildAAR();
}
/// <summary>
/// 导出Android Studio工程
/// </summary>
/// <param name="autoOpenBuildFile">是否自动打开文件夹</param>
/// <returns></returns>
private static bool BuildAndroidStudioProject(bool autoOpenBuildFile = true)
{
bool isBuildSucceed = false;
if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
{
EditorUtility.DisplayDialog("打AAR包失败", "请切换到Android平台", "确认");
return false;
}
// 设置成Gradle打包
EditorUserBuildSettings.androidBuildType = AndroidBuildType.Release;
EditorUserBuildSettings.buildScriptsOnly = false;
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
//AutoBuilder.GetScenePaths();
List<string> scenes = new List<string>();
foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes)
{
if (e != null && e.enabled)
scenes.Add(e.path);
}
var publisPath = GetPublishPath(true);
// BuildOptions必须设置为AcceptExternalModificationsToPlayer,不然的话会打出不带后缀的文件,不是导出AndroidStudio工程
BuildReport message = BuildPipeline.BuildPlayer(scenes.ToArray(), publisPath, BuildTarget.Android, BuildOptions.None | BuildOptions.AcceptExternalModificationsToPlayer);
BuildSummary summary = message.summary;
if (summary.result == BuildResult.Succeeded)
{
UnityEngine.Debug.Log("Build succeeded: " + summary.totalSize + " bytes");// todoLX 之后把字节转化为mb,gb等其他单位,便于观看
isBuildSucceed = true;
if (autoOpenBuildFile)
OpenDirectory(publisPath);
}
else if (summary.result == BuildResult.Failed)
{
UnityEngine.Debug.Log("Build failed");
isBuildSucceed = false;
}
return isBuildSucceed;
}
/// <summary>
/// 生成AAR
/// </summary>
private static void BuildAAR()
{
string projectPath = GetPublishPath(false) + "/" + "unityLibrary";
if (!Directory.Exists(projectPath))
{
UnityEngine.Debug.LogError("Android Studio Project was not found: " + projectPath);
return;
}
else
{
if (SetupAndroidStudioProject(projectPath))
{
//int lastIndex = Application.dataPath.LastIndexOf("/");
//string path1 = Application.dataPath.Substring(0, lastIndex) + "/BulidAAR";
//UnityEngine.Debug.Log("path=" + path1);// todoLX 会报错,未查原因
string path = Application.dataPath.Replace("/Assets", "") + "/BuildAAR";
File.Copy(path + "/BuildAAR.bat", projectPath + "/BuildAAR.bat", true);
Process proc = Process.Start(projectPath + "/BuildAAR.bat");
proc.WaitForExit();
}
}
}
/// <summary>
/// 设置Android Studio工程一些参数
/// </summary>
/// <param name="projectPath"></param>
private static bool SetupAndroidStudioProject(string projectPath)
{
if (null == andoridFiles)
andoridFiles = new Dictionary<string, string>();
else
andoridFiles.Clear();
FindFiles(andoridFiles, projectPath, androidNeedUpdateFile);
var count = 0;
foreach (var temp in andoridFiles)
{
//UnityEngine.Debug.Log("key: " + temp.Key + "---value: " + temp.Value);
if (temp.Key.Equals("build.gradle"))
{
if (UpdateBuildGradle(temp.Value))
{
++count;
UnityEngine.Debug.Log("修改了" + temp.Key + "文件");
}
}
if (temp.Key.Equals("AndroidManifest.xml"))
{
if (UpdateAndroidManifest(temp.Value))
{
++count;
UnityEngine.Debug.Log("修改了" + temp.Key + "文件");
}
}
}
if (androidNeedUpdateFile.Count != count)
{
UnityEngine.Debug.Log("有文件漏改了");
return false;
}
return true;
}
/// <summary>
/// 修改build.gradle
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private static bool UpdateBuildGradle(string filePath)
{
if (!File.Exists(filePath))
return false;
try
{
StreamReader reader = new StreamReader(filePath);
var content = reader.ReadToEnd().Trim();
reader.Close();
// todoLX
if (content.Contains("implementation fileTree(dir: 'libs', include: ['*.jar'])"))
content = content.Replace("implementation fileTree(dir: 'libs', include: ['*.jar'])", "api fileTree(dir: 'libs', include: ['*.jar'])");
// 将【Application】改成【Library】(library编译后的产物.aar可以发布到仓库供多个项目使用)
if (content.Contains("com.android.application"))
content = content.Replace("com.android.application", "com.android.library");
//去掉applicationId(只有 Android 应用才能定义 applicationId ,不然编译会报错的)
if (!content.Contains("//applicationId") && content.Contains("applicationId"))
content = content.Replace("applicationId", "//applicationId");
StreamWriter writer = new StreamWriter(new FileStream(filePath, FileMode.Create));
writer.WriteLine(content);
writer.Flush();
writer.Close();
}
catch (Exception e)
{
UnityEngine.Debug.Log("UpdateAndroidManifest - Failed: " + e.Message);
return false;
}
return true;
}
/// <summary>
/// 修改AndroidManifest.xml
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private static bool UpdateAndroidManifest(string filePath)
{
if (!File.Exists(filePath))
return false;
try
{
StreamReader reader = new StreamReader(filePath);
var content = reader.ReadToEnd().Trim();
reader.Close();
//去掉 intent-filter 标签
var firstStr = "<intent-filter>";
var secondStr = "</intent-filter>";
var firstIndex = content.IndexOf(firstStr);
var lastIndex = content.LastIndexOf(secondStr);
var count = lastIndex - firstIndex + secondStr.Length;
if (firstIndex > 0 && count > 0)
content = content.Remove(firstIndex, count);
StreamWriter writer = new StreamWriter(new FileStream(filePath, FileMode.Create));
writer.WriteLine(content);
writer.Flush();
writer.Close();
}
catch (Exception e)
{
UnityEngine.Debug.Log("UpdateAndroidManifest - Failed: " + e.Message);
return false;
}
return true;
}
private static void FindFiles(Dictionary<string, string> findFiles, string path, List<string> needFindFiles)
{
if (!Directory.Exists(path))
return;
DirectoryInfo dirInfo = new DirectoryInfo(path);
var files = dirInfo.GetFileSystemInfos();
for (int i = 0; i < files.Length; ++i)
{
var fileName = files[i].Name;
if (fileName.Contains("."))//文件
{
string fileFullName = files[i].FullName;
if (needFindFiles.Contains(fileName))
{
if (findFiles.ContainsKey(fileName))
findFiles[fileName] = fileFullName;
else
findFiles.Add(fileName, fileFullName);
}
}
else//文件夹,进入递归
FindFiles(findFiles, files[i].FullName, needFindFiles);
}
}
/// <summary>
/// Android Studio工程输出路径
/// </summary>
/// <returns></returns>
private static string GetPublishPath(bool isBulid)
{
int lastIndex = Application.dataPath.LastIndexOf("/");
string publishPath = Application.dataPath.Substring(0, lastIndex) + path_Output;
if (isBulid)
{
if (!Directory.Exists(publishPath))
{
Directory.CreateDirectory(publishPath);
}
}
return publishPath;
}
#region 打开文件夹
private static void OpenDirectory(string path)
{
// 新开线程防止锁死
Thread newThread = new Thread(new ParameterizedThreadStart(CmdOpenDirectory));
newThread.Start(path);
}
private static void CmdOpenDirectory(object obj)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c start " + obj.ToString();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
p.Close();
}
#endregion
}
(2)结合上面代码内容,配置批处理文件
该批处理文件,路径为【项目名称\BuildAAR\BuildAAR.bat】
cd /d %~dp0
start gradle clean assembleRelease
正确打包AAR成功之后显示下图
(3)报错记录
(3.1)打包AAR过程中出现报错(可能是由于gradle版本导致)
(4)解决方式(确认Gradle版本)
I.关掉后台【OpenJDK platform binary】
II.关掉【Unity】,【Unity Hub】
III.检查【gradle】环境配置,具体检查方法在上面的步骤2中(可搜索“确认Gradle版本”)
IV.重启【Unity Hub】,【Unity】
4.Untiy 关于 Android 配置资料
(1)Unity打包安卓工程后,根目录下build.gradle文件,里面的依赖项描述
(2)自己安装的Gradle版本,需要兼容之前在Unity安装时候附带的Gradle版本
(3)查找Unity安装时附带的Gradle版本
当前奇瑞项目使用Unity版本为2021.3,所以对应官方给的表格,附带的Gradle版本为6.1.1
*(4)自定义修改配置项
Unity Preference面板中,Android配置,包括JDK、SDK、NDK、Gradle的配置
(因时间关系,未能做修改配置打包测试,后面找时间再看)
相关资料:https://blog.csdn.net/osuckseed/article/details/93089977
文章来源:https://www.toymoban.com/news/detail-735691.html
欢迎各位补充/评论文章来源地址https://www.toymoban.com/news/detail-735691.html
到了这里,关于Unity中打包AAR流程(含环境配置)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!