亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式相关的知识,希望能为你提供帮助。
一、前言上篇说清楚了Unity和android调用的方式,但很多实际接入的部分没有讲的很详细,因为重头在这篇,会详细讲述具体接入Android SDK的方式,和怎么去做一个方便Unity接入的SDK。
传送门:
前篇:Unity3d 与 Android之间的互相调用
http://blog.csdn.net/yang8456211/article/details/51331358
后篇:Unity3d Android SDK接入解析(三)接入Android Library的理解
http://blog.csdn.net/yang8456211/article/details/51435465
二、中篇:Unity3d Android SDK的设计与两种接入方式(Android SDK的接入一般分为两种)
1)一种是把Unity的工程导出google project的形式进行接入
2)另一种是通过把Android的工程做成Plugins的形式进行接入
对比:
类别(形式) | google project | U3d Plugins |
---|---|---|
优点 | 容易理解、方便接入原生SDK、几乎所有SDK都可以接入 | 接入方便、容易在Unity中进行扩展与管理 |
缺点 | 接入比较繁琐,对U3d项目不友好 | 不是所有SDK都提供U3d Plugins形式 |
apk导出 | Android IDE导出 | Unity 导出 |
如果做一个sdk,还是推荐分开Android形式的SDK(可以是Library),与Unity3d形式的SDK(Plugins),因为一般项目会有自己的SDK架构,而让他们打破这个架构,导出Google project的形式进行接入,这无疑是很难被接受的。下面我们就来说一下具体的操作:
首先我们会自己写一个SDK,并说明白其中的注意点,然后会用两种方式接入这个SDK。
2.1 一个简单Android SDK这个SDK实现几个小功能,实现四个方法:
- init方法,用来传入上下文
- 传入两个数返回他们的和
- 传入msg,弹出一个Toast提示
- 弹出一个提示窗口,窗口需要的文字信息从strings.xml里面获取,点击确认关闭
1)实现SDK时一定要存在一个中间件Activity继承UnityPlayerActivity吗?
网上几乎所有教程都是这样教的,新建一个MyActivity,然后继承UnityPlayerActivity,在MyActivity里面写接口,然而根本没有讲清楚为什么要这样做。。
有关于这种方式的一些研究请看前篇:
http://blog.csdn.net/yang8456211/article/details/51331358。
2)让我们抛弃MyActivity吧
对于1)的问题,答案是NO,简单说一下我的理解,只有当需要在Activity的生命周期中执行一些操作时,我们才需要一个中间Activity去完成这些与生命周期相关的操作,而其他情况下,一个Class足以。那就让我们开始吧:
- 新建一个Android Project callAndroid
文章图片
- 删除其中MainActivity和activity_main.xml
文章图片
- 新建一个java class 取名CallMethod,写好上述四个方法。(可以自己先写写,然后看跟我写的有什么不一样)
public class CallMethod {
private static Context unityContext;
private static Activity unityActivity;
private static AlertDialog.Builder alert;
//init方法,用来传入上下文
public static void init(Context paramContext){
unityContext = paramContext.getApplicationContext();
unityActivity = (Activity) paramContext;
}//传入两个数返回他们的和
public static int add(int arg0, int arg1){
return arg0 + arg1;
}//传入msg,弹出一个Toast提示
public static void showMessage(final String msg){unityActivity.runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(unityContext,msg, Toast.LENGTH_LONG).show();
}
});
}//弹出一个提示窗口,窗口需要的文字信息从strings.xml里面获取,点击确认关闭
public static void showAlertView(){alert = new AlertDialog.Builder(unityActivity).setTitle("弹出窗口").setMessage(unityContext.getResources().getIdentifier("msgAlert", "string", unityContext.getPackageName())).setPositiveButton("确认", new DialogInterface.OnClickListener() {@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
unityActivity.finish();
}
});
unityActivity.runOnUiThread(new Runnable()
{
public void run()
{
alert.show();
}
});
}
}
这一小段代码,含金量可不小,能解决绝大部分你所遇到的问题~
1. 不使用Activity,那Activity上下文怎么来?
使用init的方法让Unity传当前上下文进来,我们就能拿到当前的Activity和应用上下文。(至于Unity怎么拿上下文,前篇我没有明确指出,但是我是有提的~请保持思考!)
2. 怎么弹出窗口?怎么对界面进行操作?
Unity调用Android方法默认不是在UI主线程上执行的,所以如果你想要对UI界面进行操作,那就要使用runOnUiThread才行。
3. 使用Plugins接入的时候,怎么才能读到R的资源?
这个问题困扰了我挺久的,因为直接把libs放入到Plugins中会导致读取不到资源,最后是通过反编译各种第三方SDK,才找到方法。此处是通过unityContext.getResources().getIdentifier(“msgAlert”, “string”, unityContext.getPackageName())这种java反射机制获取。(这里是获取了一个string,类比其他)
4. 只能使用静态方法吗?
当然不是,也可以使用实例方法,只是静态方法更容易调用,想要使用实例方法,我们可以创建一个单例,然后使用这个单例去调用实例方法。
private static CallMethod invokeSingleTon = null;
public static CallMethod getInvokeClass(){
if (invokeSingleTon == null){
invokeSingleTon = new CallMethod();
}
return invokeSingleTon;
}public void sayhello(){
//方法内容
}
3)怎么发布我们的SDK呢?
此时我们就已经写好了我们的SDK,这个SDK比较健壮,怎么发布都行,可以勾上isLibrary以Android的库文件的形式进行发布;也可以分离出jar和res,以代码和资源的方式进行发布。
2.2 一个简单Unity工程在写完AndroidSDK之后,我们简单的写一个Unity的工程,用来调用Android设置的接口。
- 首先建立一个空的Unity工程,命名为UnityCall
- 选中摄像机MainCamera,新建一个CS脚本callAnd
文章图片
- 绑定到Main Camera
选中Main Camera,在add component的地方,选择刚才写的callAnd脚本
文章图片
AndroidJavaClass unityPlayer;
AndroidJavaObject currentActivity;
AndroidJavaClass androidCall;
void Start () {
//获取context
unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
currentActivity = unityPlayer.GetStatic<
AndroidJavaObject>
("currentActivity");
androidCall = new AndroidJavaClass("com.atany.callandroid.CallMethod");
androidCall.CallStatic("init",currentActivity);
}void Update () {
}void OnGUI()
{
GUI.skin.textArea.fontSize = 50;
GUI.skin.button.fontSize = 50;
// add
if(GUI.Button(new Rect(100,300,450,300),"add"))
{
int sum = androidCall.CallStatic<
int>
("add",1,2);
print ("sum is "+ sum);
} // showMessage
if(GUI.Button(new Rect(600,300,450,300),"showMessage"))
{
androidCall.CallStatic("showMessage","显示这一段的文字");
}// showAlertView
if(GUI.Button(new Rect(100,700,450,300),"showAlertView"))
{
androidCall.CallStatic("showAlertView");
}
}
画了三个button,用于调用我们设置好的Android三个不同的功能。
2.3 导出Android工程进行接入首先呢,我们就先试一试导出Android工程的接入形式,把我们的Unity工程导出,然后接入我们的Android SDK。
- 导出Android 工程(快捷键 Shift+Ctrl+b调出Build Settings)
文章图片
- 导入到IDE 这里使用eclipse,当然Idea也是一样的
文章图片
- 我们把Android SDK打成jar+res(就一个stringnew.xml)的形式发布,加入到Unity导出的工程中。
文章图片
add:
点击add成功收到Unity3d打印的返回值。
文章图片
showMessage:
点击showMessage,成功在当前界面显示了toast。
文章图片
showAlertView:
点击showAlertView,成功在界面弹出了对话框
文章图片
OK,到这里我使用导出google project的方法实现的android sdk的接入!也说明我们的资源读取的方式是正确的(取到stringnew里面的字符串资源),能够弹出对话框和Toast就意味着你能够实现各种可视化的界面操作。接着,我们看看怎么使用Unity插件的形式进行接入。
2.4 使用Unity插件形式进行接入这种形式更加简单,简而言之就是以U3d要求的一种形式放好你的资源和jar包,然后就能够运行了~
- 构建Plugins的形式
我们还是用之前新建的U3d的工程,记得开始的时候我们只添加了一个脚本,现在我们要在assets下面建立如下的结构:
文章图片
Plugins:assets 下的根目录(下面可能有Android或者ios) Android:主目录 bin:放中间件的工程(我们没有建立MyActivity的中间件,如果有的话放在这里) libs:放所有jar包 res:放所需要的资源
- 放入我们刚导出的Android SDK的libs和res
文章图片
1.callAndroid的jar是放在libs里面的,stringnew这个xml是放在values里面的,我是通过多选让大家看看我添加的所有文件
2.如果bin里面有加入中间件MyActivity,或者有需要添加的权限以及Android的组件,需要放入AndroidManifest到Android目录下。
- 运行效果和导出google project的效果是一样的,我就不重新贴图贴一次了。
如果你跟着我做完了,你应该理解到的内容:
1. 正确的完成一个方便Unity接入的SDK
2. 使用导出工程的模式完成SDK的接入
3. 使用Unity插件的形式进行Android的接入
后篇我会讲讲具体的例子,怎么接入一个具体的Android的Library工程。
三、demo地址Android接入demo分为三个工程:
- UnityCall:Plugins形式的Unity3d的工程
- EclipseProj:Android的两个工程
UnityPlayerNativeActivity:Unity3d导出式的工程
callAndroid:Android的sdk工程
http://download.csdn.net/detail/yang8456211/9517718
【Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式】杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。
博文地址:http://download.csdn.net/detail/yang8456211/9517718
博客地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商业用途-保持一致”创作公用协议
推荐阅读
- Android系统源码阅读(12)(InputChannel的注册过程)
- Android性能优化之Systrace工具介绍_&&Systrace生成的trace.html打开空白或者打不开的解决办法
- Android Multimedia框架总结(十三)CodeC部分之OpenMAX框架初识及接口与适配层实现
- Android andbug 命令
- android中string.xml中%1$s%1$d等的用法
- Android系统源码阅读(13)(Input消息的分发过程)
- css伪类和伪类选择器 – CSS高级教程
- Accolite招聘经验更新(校园内)
- C++ STL中的容器介绍(标准模板库)