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

亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述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
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

  • 删除其中MainActivity和activity_main.xml
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

  • 新建一个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
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

  • 绑定到Main Camera
    选中Main Camera,在add component的地方,选择刚才写的callAnd脚本
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

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)
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

  • 导入到IDE 这里使用eclipse,当然Idea也是一样的
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

注意:这里一定要选Existing Android Code Into Workspace,不要选Existing projects into Workspace
  • 我们把Android SDK打成jar+res(就一个stringnew.xml)的形式发布,加入到Unity导出的工程中。
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片
-可以看到,我们就加入了两个东西,一个jar和一个xml,让我们跑起来看看效果
add:
点击add成功收到Unity3d打印的返回值。
Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

文章图片

showMessage:
点击showMessage,成功在当前界面显示了toast。
Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

文章图片

showAlertView:
点击showAlertView,成功在界面弹出了对话框
Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

文章图片

OK,到这里我使用导出google project的方法实现的android sdk的接入!也说明我们的资源读取的方式是正确的(取到stringnew里面的字符串资源),能够弹出对话框和Toast就意味着你能够实现各种可视化的界面操作。接着,我们看看怎么使用Unity插件的形式进行接入。
2.4 使用Unity插件形式进行接入这种形式更加简单,简而言之就是以U3d要求的一种形式放好你的资源和jar包,然后就能够运行了~
  • 构建Plugins的形式
    我们还是用之前新建的U3d的工程,记得开始的时候我们只添加了一个脚本,现在我们要在assets下面建立如下的结构:
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

    Plugins:assets 下的根目录(下面可能有Android或者ios) Android:主目录 bin:放中间件的工程(我们没有建立MyActivity的中间件,如果有的话放在这里) libs:放所有jar包 res:放所需要的资源

  • 放入我们刚导出的Android SDK的libs和res
    Unity3d Android SDK接入解析Unity3d Android SDK的设计与两种接入方式

    文章图片

注意:
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分为三个工程:
  1. UnityCall:Plugins形式的Unity3d的工程
  2. 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
本文遵循“署名-非商业用途-保持一致”创作公用协议






























    推荐阅读