参考链接:https://blog.csdn.net/ZhangDi2017/article/details/65629589
最近负责项目的SDK接入,之前没使用过Android Studio,基本算是从零学起,大部分内容参考自逝水追风的博客,并结合我的实际情况进行了修改、优化,谨以此篇记录所学
PlaybackEngines
文件夹,AndroidPlayer/Variations/mono/Development/Classes/classes.jar
启动Android Studio新建一个Project,会弹出创建工程向导,这里可以随意填写Package Name和Mininum SDK,最后让选择的Activity类型也可以随意。因为我们并不会用到现在创建的这个项目,我们只是在其结构上再创建一个Library作为我们的Plugin。这里值得注意的是,根据你填写的Company domain和Application name生成的Package name总是小写的,点击右侧的Edit按钮可以对其进行修改。
创建项目点击Finish后进入编辑器界面,空无一物,点击左侧的Project,然后切换至Project视图,如图下图左所示。随后在项目名称上点击右键选择New -> Module来创建一个新的模块,这时新的创建向导会启动,选择Android Library类型,随后输入包名的配置与Mininum SDK,注意这里的Package Name需要和Unity项目中的Bundle Identifier保持不一致,同时也要避免与其他模块重名,原因是下面要使用Unity的Gradle模式打包,重名会导致打包失败;而Mininum Required SDK最好选择4.0以上,要不然还需要引入android-support-v7兼容包,而且随后会用到Android 3.0之后才支持的Fragment特性(请先确定Unity支持的最低版本,我的Unity支持的Android版本最低为4.1(API level 16)),最后点击Finish完成创建。
在新的Library创建完成后,需要删除app相关的内容。点击菜单栏File -> Project Structure,在Modules中选中app然后点击上方的-
号,选择YES,最后点击OK,稍等一会儿,等待系统编译。
如果不小心点到最上边Modules右边的-
,按下图所示重新打开即可
展开刚创建的Library目录如下图中所示,以后所有的开发操作都会在创建的这个Library下面进行。下面对项目的结构进行一些说明。build/outputs/aar文件下面是构建生产的供Unity使用的aar文件(aar文件和jar文件类似,Unity可以识别,如果没有aar文件,通过Build->Rebuild Project重新编译一下);libs文件夹下面是项目以来的类库,可以说各种SDK的jar等等;最后是src文件夹,这里面存放了AndroidManifest以及源码。这些内容有一些是不需要的,例如一些单元测试的内容,我们删掉测试工程以及res下面的Android自带的资源及配置(白框部分),只保留了AndroidManifest.xml。
接下来是配置AndroidManifest的内容。双击打开AndroidManifest.xml,如果里面有一些红色的内容,那些是因为刚才各种删除导致的,删掉其余不相关的内容,只保留最基础的东西(原文内容,我测试过程中没有出现上述情况)
最后就是编写自己的插件或者对接第三方SDK了。首先引入Unity的jar包(Mac中位置:在应用程序中找到unity app 同级目录下的PlaybackEngines
文件夹AndroidPlayer/Variations/mono/Development/Classes/classes.jar
)
将classes.jar拷贝到文件夹里libs文件夹下面,还是点击File -> Project Structure,在左侧选择Dependencies,选择自己创建的插件,先删除的现存的所有依赖库,然后点击 如果第三方依赖库中有so文件,先不需要导入,稍后将会说明如何添加so文件。如果库文件为 *.jar(Unity的jar包) *.aar(例如支付宝),千万不要这样导入,具体参考补充第2条,这样只需要导入一次而已,不用每开发一个插件,都要导入一次jar包, 并且打出的aar包中不会包括引用库,也就不会引起打包冲突 。到这一步,项目、依赖库都设置完毕。+
号 ->Jar Dependency添加Unity的jar包,点击OK完成设置。对于第三方SDK的jar包,以同样的方式进行引入。
创建MyPluginClass类
不要再继承UnityPlayerActivity了1!具体原因后面的参考资料里给出。首先贴一段Android Studio里的示例代码,这里用一个单例作为这个类访问的入口,在Unity中只需要拿到Instance进行操作即可,里面涉及到一些Android原生的Fragment的操作,具体含义可以Google一下:
package com.soulgame.myplugin;
import android.app.Fragment;
import android.os.Bundle;
import com.unity3d.player.UnityPlayer;
public class MyPluginClass extends Fragment
{
private static final String TAG = "TestLibrary";
private static MyPluginClass Instance = null;
private String gameObjectName;
public static MyPluginClass GetInstance(String gameObject)
{
if(Instance == null)
{
Instance = new MyPluginClass();
Instance.gameObjectName = gameObject;
UnityPlayer.currentActivity.getFragmentManager().beginTransaction().add(Instance, TAG).commit();
}
return Instance;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true); // 这一句很重要,保存对该Fragment的引用,防止在旋转屏幕等操作时时丢失引用(Fragment隶属于Activity)
}
//示例方法一:简单的向Unity回调
public void SayHello()
{
UnityPlayer.UnitySendMessage(gameObjectName,"PluginCallBack","Hello Unity!");
}
//示例方法二:计算传入的参数并返回计算结果
public int CalculateAdd(int one, int another)
{
return one + another;
}
//示例方法三:返回拼接字符串
public String GetPluginString(String str){
return "Get Plugin Back "+str;
}
}
在Unity中编写如下示例代码调用插件的三个方法:
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
public string className = "com.xxx.xxx.MyPluginClass";// 同上面被屏蔽的包名,后面拼接Java类名
public Text callbackText = null;
public Text resultText = null;
public Text resultText1 = null;
private AndroidJavaObject pluginObject = null;
// Use this for initialization
void Start()
{
#if UNITY_ANDROID
pluginObject = new AndroidJavaClass(className).CallStatic<AndroidJavaObject>("GetInstance", gameObject.name);
pluginObject.Call("SayHello");
resultText.text = pluginObject.Call<int>("CalculateAdd", 22, 33).ToString();
resultText1.text = pluginObject.Call<string>("GetPluginString", "你好");
#endif
}
public void PluginCallBack(string text)
{
callbackText.text = text;
}
}
两边都编写完成,开始将插件编译导出:选中Android Studio最右侧(默认布局)的Gradle,选中如图所示的选项编译输出,稍等一会儿,在左侧的Project面板可以看到相关的aar文件了
这个aar文件就是最终输出给Unity使用的aar包,(如果使用补充第2条的方法打出的aar包则不需要进行下面的解压再压缩操作) 拿到aar包之后,需要进行一项关键的操作,将其后缀改为压缩格式(zip或rar)打开压缩包删除掉libs/下面的classes.jar(原因是Unity在打包的时候会再次拷贝安装目录下的classes.jar到项目中造成冲突,另,ios解压之后不要直接对文件夹压缩,要把文件夹里面的内容打成一个压缩包,再改名,蛋疼)!如果插件使用到了so文件,将对应平台的so文件拷贝至libs下面
错误做法:
正确做法:
最后将aar文件后缀改回为aar拷贝至Unity工程中Plugins/Android文件夹下,不再需要AndroidManifest.xml!设置好Platform和Bundle Identifier以及Mininum API Level(和插件保持一致),到真机上测试即可。
我的unity工程打包最后报错,大概错误是版本问题,我把插件中的build.gradle中的compileSdkVersion改为了22,将图示的两行版本注释掉,重新生成aar包,删除libs/classes.jar,再导入unity,打包通过。。。
使用adb命令在手机上安装之后,运行,可以看到测试的三个方法都已经执行成功
通过自我摸索、反复测试,终于成功,又学到了新知识,填补了知识盲区。上述内容可能有巧合成分,也可能有错误,欢迎留言斧正
经过几天的学习与踩坑,总结一下:
不要再继承UnityPlayerActivity的原因 ↩︎