最近需要接SDK就研究了一下,个人是个AS小白,写的有啥不对的,欢迎个为大佬指正
一:创建Android工程
1.新建一个空工程或者带有项目的工程(建议建一个带有项目的工程,里边有示例代码可以参考,而且有相关的引用)
2.项目名和包名都可以随便写
3.如下图添加要导出的项目库
4.编辑自己的项目库名称和包名(注意:包名仅为此sdk使用,最好不要与unity项目的包名相同,可能unity打包时会冲突)
5.建好的项目目录如下图:
6.将sdk的jar包和arr包放到上图1(libs)目录下,如果需要回调unity的话可以把unity的class.jar包也放到里边
6.1 我的Unity版本为2019.4.9f1,class.jar所在目录为Unity安装目录下的如下图路径,其他版本的百度一下
6.2 回调unity的话需要将UnityPlayerActivity.java也放入工程,并且java脚本要继承UnityPlayerActivity,所在目录如下图
6.3 将unity3d整个文件夹copy到AS工程自己的库目录com文件夹下即可
6.4 将导入的jar包同步到项目,如下图
6.5 arr包的话需要在自己的库目录下的build.gradle中添加引用,如下图
上图1,2步骤一般对接的sdk说明文档中都会写,3.步骤是同步到工程(上边的arr是我随便找的)
7. 写自己的java代码
8.AS回调Unity
package com.xiaotao.mylibrary;
import android.os.Bundle;
import android.util.Log;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import static android.content.ContentValues.TAG;
public class ASCallUnity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private static ASCallUnity m_instance;
public static ASCallUnity Instance()
{
if (null == m_instance)
m_instance = new ASCallUnity();
return m_instance;
}
//示例代码,java回调unity,其实和unity中的发送消息给对象是一样的
public void SendMsg()
{
//第一个参数为unity中的对象名称
//第二个参数为unity对象脚本中的方法
//第三个参数为unity对象脚本中的方法中需要传的参数,这个参数看方法,包括参数类型,有的话就传,没有的话可以不穿
//UnityPlayer.UnitySendMessage("gameObjectName", "_funcStr", "args");
Log.d(TAG, "CallUnity: 向Unity发送消息");
UnityPlayer.UnitySendMessage("ASCall", "AsCallTest", "ASCallUnity");
}
}
9. 自己的java脚本
package com.xiaotao.mylibrary;
import android.app.Application;
import android.util.Log;
import static android.content.ContentValues.TAG;
public class MainClass extends Application {
@Override
public void onCreate() {
super.onCreate();
//一般Sdk的初始方法要在这里运行
//TODO 初始方法
//Init();
}
private static MainClass m_instance;
public static MainClass Instance()
{
if (null == m_instance)
m_instance = new MainClass();
return m_instance;
}
//unity调用不带参函数
public void UnityCallJava()
{
Log.d(TAG, "UnityCallJava: + 调用不带参函数");
}
//unity调用带参函数
public void UnityCallJavaArg(String str)
{
Log.d(TAG, "UnityCallJavaArg: 调用带参函数: " + str);
}
}
二.完成功能后导出包供Unity使用
1.选中自己的项目库按照下图操作
2.导出后进入到文件夹处理arr包
3.生成的arr包可以直接使用或者仅需要arr中的classes.jar文件
3.1 如果arr包中有自己的图片资源或view的xml文件,那直接导入unity就可以用了(前提是arr包里边不包含unity的class.java文件,如果有的话,用压缩软件打开,删掉就行)
3.2 如果自己仅写了java逻辑代码的话可以进行简化arr包,删除多余资源,步骤如下:
3.2.1双击用快压打开
3.2.2.打开后将最外边的classes.jar拉出到文件夹(为的是剔除unity相关的类库,防止unity打包时冲突)
3.2.3.打开文件夹中的classes.jar,将unity的脚本删掉
三.导入Unity
1.创建如下图文件夹并将classes.jar(名称可以自己命名)放入到libs文件夹下
2.写C#代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Demo : MonoBehaviour
{
private Button m_btn1;
private Button m_btn2;
private Button m_btn3;
private AndroidJavaObject m_mainClass;
private AndroidJavaObject m_callClass;
// Start is called before the first frame update
void Start()
{
m_btn1 = GameObject.Find("Btn_1").GetComponent<Button>();
m_btn1.onClick.AddListener(CallASFun);
m_btn2 = GameObject.Find("Btn_2").GetComponent<Button>();
m_btn2.onClick.AddListener(CallASFunWithArg);
m_btn3 = GameObject.Find("Btn_3").GetComponent<Button>();
m_btn3.onClick.AddListener(CallASFunToUnity);
var ASCallUnity = new AndroidJavaClass("com.xiaotao.mylibrary.ASCallUnity");
m_callClass = ASCallUnity.CallStatic<AndroidJavaObject>("Instance");
var mainClass = new AndroidJavaClass("com.xiaotao.mylibrary.MainClass");
m_mainClass = mainClass.CallStatic<AndroidJavaObject>("Instance");
}
public void AsCallTest(string str)
{
Debug.Log("----AsCallTest-----:" + str);
}
private void CallASFun()
{
Debug.Log("----CallASFun----");
m_mainClass.Call("UnityCallJava");
}
private void CallASFunWithArg()
{
Debug.Log("----CallASFunWithArg----");
m_mainClass.Call("UnityCallJavaArg", "unity调用java");
}
private void CallASFunToUnity()
{
Debug.Log("----CallASFunToUnity----");
m_callClass.Call("SendMsg");
}
}
3.AndroidManifest.xml编辑,按照sdk说明文档添加相关设置,该文件没有的话可以从Unity安装目录下copy放到工程Plugins -> Android目录下然后修改名字为AndroidManifest.xml,如下图
4.打出的apk可能闪退,在AS打印的日志,说是找不到class
处理方法如下图:
然后在mainTemplate中添加相关依赖
项目工程地址:https://pan.baidu.com/s/11S_cF3bKarj86iIXbYDoYw 提取码:i9ep
四.过程中的相关报错总结
1.SDK location not found.
翻译的意思是:未找到SDK位置。使用local.properties文件中的sdk.dir或ANDROID\u HOME环境变量定义位置。
解决方法:在app目录下新建local.properties文件,文件内容如下所示:
里边的内容
sdk.dir=D\:\\Software\\Android\\Sdk是我的Android sdk的安装目录
配置好后gradle重新Reload就可以
2.error: unknown element found.
解决方法:
将项目下的build.gradle中的BuildTools 插件版本改为4.0.0以上的,如下
unity报错,
由于Android11新标签不识别问题导致,修改unity安装路径Editor\Data\PlaybackEngines\AndroidPlayer\Tools\GradleTemplates下的baseProjectTemplate.gradle文件
classpath 'com.android.tools.build:gradle:3.4.0'
修改为
classpath 'com.android.tools.build:gradle:3.4.3'
3.Minimum supported Gradle version is 6.5. Current version is 6.1.1.
配置好2后可能出现3这种情况,因为配置的BuildTools 插件版本与当前的Androi Studio版本不匹配
解决方法:
可以直接修改它为6.5.0然后Sync Now或者Reload Gradle Project
或者直接点它
4.AAPT: error: attribute android:requestLegacyExternalStorage not found.
解决方法:
需要将Android SDK build tool 更新到29
改为29后同步一下
5.No version of NDK matched the requested version 21.0.6113669. Versions available locally: 23.0.7272597
翻译后意思为:没有与请求的版本21.0.6113669匹配的NDK版本。本地可用版本:23.0.72597
解决方法:
直接点击蓝色字Install NDK “xxx”等待下载后同步
6.项目下build.gradle的dependencies中可能爆红
原因:Android SDK build tool 版本 >28导致,
解决方法:6.1 如果Android SDK build tool 必须要使用大于28的版本这个爆红可以不处理(会出现什么问题还不知道,暂时没遇到)
6.2 修改Android SDK build tool 版本为28
7.Unity打包apk报错: Cannot fit requested classes in a single dex file (# methods: 73376 > 65536)的解决办法
转载:https://blog.csdn.net/MRYZJ/article/details/103463212
推荐:https://blog.csdn.net/chenliguan/article/details/73750138