上篇说清楚了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
1)一种是把Unity的工程导出google project的形式进行接入
2)另一种是通过把Android的工程做成Plugins的形式进行接入
对比:
类别(形式) | google project | U3d Plugins |
---|---|---|
优点 | 容易理解、方便接入原生SDK、几乎所有SDK都可以接入 | 接入方便、容易在Unity中进行扩展与管理 |
缺点 | 接入比较繁琐,对U3d项目不友好 | 不是所有SDK都提供U3d Plugins形式 |
apk导出 | Android IDE导出 | Unity 导出 |
建议:
首先我们会自己写一个SDK,并说明白其中的注意点,然后会用两种方式接入这个SDK。
这个SDK实现几个小功能,实现四个方法:
先回答一个可能困惑大家问题:
网上几乎所有教程都是这样教的,新建一个MyActivity,然后继承UnityPlayerActivity,在MyActivity里面写接口,然而根本没有讲清楚为什么要这样做。。
有关于这种方式的一些研究请看前篇:
http://blog.csdn.net/yang8456211/article/details/51331358。
对于1)的问题,答案是NO,简单说一下我的理解,只有当需要在Activity的生命周期中执行一些操作时,我们才需要一个中间Activity去完成这些与生命周期相关的操作,而其他情况下,一个Class足以。那就让我们开始吧:
新建一个Android Project callAndroid
新建一个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(){
//方法内容
}
此时我们就已经写好了我们的SDK,这个SDK比较健壮,怎么发布都行,可以勾上isLibrary以Android的库文件的形式进行发布;也可以分离出jar和res,以代码和资源的方式进行发布。
在写完AndroidSDK之后,我们简单的写一个Unity的工程,用来调用Android设置的接口。
绑定到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三个不同的功能。
首先呢,我们就先试一试导出Android工程的接入形式,把我们的Unity工程导出,然后接入我们的Android SDK。
注意:这里一定要选Existing Android Code Into Workspace,不要选Existing projects into Workspace
-可以看到,我们就加入了两个东西,一个jar和一个xml,让我们跑起来看看效果
add:
点击add成功收到Unity3d打印的返回值。
showMessage:
点击showMessage,成功在当前界面显示了toast。
showAlertView:
点击showAlertView,成功在界面弹出了对话框
OK,到这里我使用导出google project的方法实现的android sdk的接入!也说明我们的资源读取的方式是正确的(取到stringnew里面的字符串资源),能够弹出对话框和Toast就意味着你能够实现各种可视化的界面操作。接着,我们看看怎么使用Unity插件的形式进行接入。
这种形式更加简单,简而言之就是以U3d要求的一种形式放好你的资源和jar包,然后就能够运行了~
构建Plugins的形式
我们还是用之前新建的U3d的工程,记得开始的时候我们只添加了一个脚本,现在我们要在assets下面建立如下的结构:
Plugins:assets 下的根目录(下面可能有Android或者IOS)
Android:主目录
bin:放中间件的工程(我们没有建立MyActivity的中间件,如果有的话放在这里)
libs:放所有jar包
res:放所需要的资源
注意:
1.callAndroid的jar是放在libs里面的,stringnew这个xml是放在values里面的,我是通过多选让大家看看我添加的所有文件
2.如果bin里面有加入中间件MyActivity,或者有需要添加的权限以及Android的组件,需要放入AndroidManifest到Android目录下。
如果你跟着我做完了,你应该理解到的内容:
1. 正确的完成一个方便Unity接入的SDK
2. 使用导出工程的模式完成SDK的接入
3. 使用Unity插件的形式进行Android的接入
后篇我会讲讲具体的例子,怎么接入一个具体的Android的Library工程。
http://download.csdn.net/detail/yang8456211/6369199
杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。
博文地址:http://download.csdn.net/detail/yang8456211/9517718
博客地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商业用途-保持一致”创作公用协议