Unity3D项目实战笔记(4):Unity3D接入Android SDK

Unity3D做手游,强于UI和业务逻辑处理;但一些与手机相关的操作,需要依赖Android系统API,且不用提一些第三方厂家的SDK接入了–原理上是大同小异。

 

开发一个Unity3D的插件,以下是步骤:

  1. 在Eclipse中新建Android Application,并选择 as libray(这样可以生成jar包而不是apk文件)
  2. jar包的最小Android SDK选择为14(即Android 4.0以上系统);且Package一定要和Unity.Identity一致。(猜测是为了方便Unity打包的时候进行合并工作)
  3. 然后在Package视图选择Build–导入Unity3D的classes.jar包(Unity安装目录下自带的)
  4. 修改默认Activity,继承为UnityPlayerActivity;并删除OnCreate中SetContentView函数。
  5. 写供Unity3D调用的的public函数。如Max、Vibrate、ShowMessage2等。
  6. (地址在本文下面,可参见我demo)
  7. export为jar包 (jar包生成放到Plugins\Android\bin\下面),
  8. 拷贝AndroidManfest.xml、res文件夹到 Plugins\Android下面
  9. Unity新建Android.cs文件,并写接入脚本(脚本文件可随便起)
  10. Unity打包apk 真机测试–PC下运行需要写条件编译,Android的方法调用会报错的。

以防万一,rar打开jar包看路径是否是Package的顺序。

 

Unity3D调用Android public函数

  • AndroidJavaClass
  • AndroidJavaObject
  • AndroidJavaProxy

系统提供了这3个函数,且都有源码demo,直接查询Unity3D官方手册即可。

 

Android回调Unity3D

方式1:UnityPlayer.UnitySendMessage("Android","onReceiveByUnitySendMessage", data);

参数 “Android”:Unity3D的GameObject名字

参数“onReceiveByUnitySendMessage”: GameObject下面一个public函数,带string传入参数

参数 data: string类型的数据,会传入到onReceiveByUnitySendMessage函数中。

方式2:Android的interface

在Android中实现一个interface; 然后在Unity3D中实现这个interface的子类;Unity调用Android的时候传递子类实例过去,则Android可以回调之。

package com.xifarm.unity3dPlugins;

public interface ExDataListener {

public void onReceive(String data);

}

 

public class ExDataListenerCallback : AndroidJavaProxy

{

private AndroidTest mMain= null;

public ExDataListenerCallback(AndroidTest main)

: base("com.xifarm.unity3dPlugins.ExDataListener")

{

    mMain = main;

}

public void onReceive(String data)

{

mMain.onReceive(data);

}

}

 

最后,在接入某个特定的Android SDK,如微信、移动MM,请务必牢记:

  1. 熟悉官方的网站
  2. 熟悉官方的SDK
  3. 熟悉官方的文档
  4. 熟悉官方的示例
  5. 熟悉官方的支持

尤其在上网找资料前(特别是百度),官方的资源基本可以解决90%的问题,无他,做为官方,这帮人是最专业,也是最系统的对待自己产品的—-这个是我在担任GCDN版主的感悟。

 

本文的源码在Git上:http://git.oschina.net/xifarm/Unity3DPlugins

Unity3D项目实战笔记(3):Android系统的AndroidManifest.xml && Activity

在接入Android SDK的时候,了解了Android多线程后, 我们来了解一下AndroidManifest.xml 和Activitiy.

在Android开发中,无main函数,这个让C\C++\C#程序员不太适应,但是Android提供了Main的入口的,这个就是配置AndroidManifest.xml。

 

  • AndroidManifest.xml

    权威的AndroidManifest.xml请直接看Google官方文档,非常详细和及时。

image

 

其中在开发Android SDk接入,需要配置 android:configChanges–keyboard|keyboardHidden|screenSize|orientation。 即当屏幕翻转等变化后,Activity不会“死掉”,会调用Activity.onConfigurationChanged() 方法.

另外,jar包中的activity,都是需要在AndroidManifest.xml声明的。

其中这个属性比较重要  android:launchMode(Activity加载模式)

在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式

Activity有四种加载模式:

  • standard (默认)
  • singleTop
  • singleTask
  • singleInstance

standard:就是intent将发送给新的实例,所以每次跳转都会生成新的activity。

singleTop:也是发送新的实例,但不同standard的一点是,在请求的Activity正好位于栈顶时(配置成singleTop的Activity),不会构造新的实例

singleTask:和后面的singleInstance都只创建一个实例,当intent到来,需要创建设置为singleTask的Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。

singleInstance:

首先说明一下task这个概念,Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,那在它的界面上调用其他的Activity也只是在这个task里面。

  • Activity

    Activity概念,可以简述为用户可见的一个大视图的主布局框架,在Android中,每次只能看到一个Activity,两个Activity切换会采用Task任务栈方式调度。

    Activity的生命周期

image

    奇怪的是Android屏幕旋转,也是需要销毁Activity的,故需要预先存储、加载数据的。
    为了实现outlook左右布局,左侧导航+右侧切换视图效果,需要用到FrageMentActivity子类。
      最后,在Activity之间通信,有2种办法:
      显示Intent

    //显示方式声明Intent,直接启动SecondActivity

    Intent it = new Intent(MainActivity.this,SecondActivity.class);

    //启动Activity

    startActivity(it);

      隐式Intent

    // 实例化Intent

    Intent it = new Intent();

    //设置Intent的Action属性

    it.setAction("com.android.activity.MY_ACTION");

    // 启动Activity

    startActivity(it);

    隐式Intent之所以设置Action后,即可找到可能的Activity,是因为Activity的intent-filter属性对外公开了其可以处理的Action。如系统默认的拨打电话、播放音乐等Activity等。

    image

    Unity3D项目实战笔记(2):Android系统的多线程

    书到用时方恨少!

    《Android编程权威指南》去年翻了半个月,仅仅看了前几章。

    产出是: 自己搭建了Android的开发环境、照着书写了几个Hello World的App,并发布到Android真机上、而最有纪念意义的就是产出了3篇博客:

    随后一年,这本Android开发的宝典落了一层灰!

    最近,手游项目中要用到Android SDK接入的技能,才恍然发现需要补补Android的基础知识,随即翻看了3篇博客,而后打开尘封已久的宝典,又“挑灯夜战”:晚上下班后,匆匆扒两口饭就翻书学习、记笔记;第二天在工作中用于实践。 自我感觉,挺好的。

    有目的的学习,威力无穷也!

    本文就Android多线程进行笔记整理之。

    Android系统中,主线程(UI线程)不能访问网络,如果违规这么干,则app会很有可能Crash的,我遇到了多次,故多线程是必须要掌握的一项Android技能。

     

    Android的多线程分3个:
    • 短时间运行的 AsyncTask

      AsyncTask可定义在主线程内,是一种最简单的Android多线程实现方法,可在AsyncTask内调用UI主线程函数。

    可通过如下代码定义AsyncTask,其中@Override的函数是AsyncTask预定义好的,直接重载即可。

    public class aaa extends AsyncTask<P1, P2, P3>  //P1是Input参数,P2是更新用,P3是Output参数

    {

        @Override P3 doInBackground(P1) //子线程的核心逻辑函数

        @Override OnPostExecute(P3);   //线程处理完毕后收尾函数,可访问主线程

        @Override OnProgressUpdate(P2); //可访问主线程,一般用于如更新ProgressBar状态等

    }

     

    取消AsyncTask用Cancel(bool)

     

    在主线程中,启动线程用这行代码:

    new aaa().Execute().

    • 专用后台线程 HandlerThread

      HandlerThread是Android系统提供的主要后台线程, 相对简单的AsyncTask,HandlerThread涉及到了Message、Looper、Handler、Queue概念。

      Looper扮演着一个Handler和消息队列之间通讯桥梁的角色。程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。 Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。

    Looper.myLooper();获得当前的Looper

    Looper.getMainLooper () 获得UI线程的Lopper

     

    • 简单的线程 runOnUiThread(Runnable)

    activity.runOnUiThread(new Runnable()

    {
    @Override public void run()

    { // TODO Auto-generated method stub

    int i = 30; textView.setText(""+i+" s");

    } } });