您的位置:首页 > 移动开发 > Unity3D

Unity3d Android SDK接入解析(二)Unity3d Android SDK的设计与两种接入方式

2016-05-12 11:06 441 查看

一、前言

上篇说清楚了Unity和Android调用的方式,但很多实际接入的部分没有讲的很详细,因为重头在这篇,会详细讲述具体接入Android SDK的方式,和怎么去做一个方便Unity接入的SDK。

传送门:

前篇:Unity3d 与 Android之间的互相调用

/article/7601650.html

后篇:Unity3d Android SDK接入解析(三)接入Android Library的理解

/article/7601652.html

二、中篇:Unity3d Android SDK的设计与两种接入方式

(Android SDK的接入一般分为两种)

1)一种是把Unity的工程导出google project的形式进行接入

2)另一种是通过把Android的工程做成Plugins的形式进行接入

对比:

类别(形式)google projectU3d 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里面写接口,然而根本没有讲清楚为什么要这样做。。

有关于这种方式的一些研究请看前篇:

/article/7601650.html

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脚本



cs脚本的代码:

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也是一样的



注意:这里一定要选Existing Android Code Into Workspace,不要选Existing projects into Workspace

我们把Android SDK打成jar+res(就一个stringnew.xml)的形式发布,加入到Unity导出的工程中。



-可以看到,我们就加入了两个东西,一个jar和一个xml,让我们跑起来看看效果

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/6369199

杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。

博文地址:http://download.csdn.net/detail/yang8456211/9517718

博客地址:http://blog.csdn.net/yang8456211

本文遵循“署名-非商业用途-保持一致”创作公用协议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: