alwaystest / Blog

24 stars 2 forks source link

Unity3D调用Android原生方法 #24

Open alwaystest opened 8 years ago

alwaystest commented 8 years ago

Unity3D调用Android原生方法

标签(空格分隔): Unity3D Android


研究Unity3D调用Android方法的时候,在网上找了许多文章,许多都是不了解Android的开发者写的,而雨松MOMO的那篇文章写于2012年,时间虽然久远但是依旧有参考价值。我要写的方法可能也需要有Android基础才能读懂,如果有疑问,可以在评论中提出。

  1. 雨松的文章讲的是把Android代码打包成Jar包,然后使用Unity来调用的。
  2. 我要写的方法是Unity导出Android项目,然后在Android Studio里面编写代码,使用Android Studio编译APK的。

以上两种方法都可以使用,目前我还不知道两种方法哪种更好。


开发环境:

首先

在Unity脚本里写调用安卓方法的时候,这个方法还不需要存在,你也不需要把安卓的代码压成jar包放进Unity工程.

我们放心的在Unity里编辑需要调用的方法。

AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo=jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("onCall","String");

代码第一行参数必须是 com.unity3d.player.UnityPlayer , 不管你Unity导出的项目是什么包名,UnityPlayer所在的包一定是unity-classes.jar中的com.unity3d.player。加载这个类的目的是为了第二行获取当前Activity的引用。

这里的写法AndroidJavaClass jc = new AndroidJavaCalss("com.zhihu.solare.MainActivity"); 是错误的,会导致我们的第二行代码找不到currentActivity。原因在UnityPlayer的代码里面。

public class UnityPlayer extends FrameLayout implements com.unity3d.player.a.a {
    public static Activity currentActivity = null;
    ......
}

currentActivity存在于UnityPlayer类中,而不是自己新建的Activity类中,也不存在于Activity的父类UnityPlayerActivity中。

UnityPlayerActivity初始化的时候会新建UnityPlayer对象,并把当前Activity的引用赋值给currentActivity。这样,我们在第二行获取到的引用就不会是null了。

代码第三行,我们调用即将在Android Studio中编写的方法onCall(String str)

写好上面的代码,就可以使用Unity导出项目了,在我现在使用的这个版本,Unity导出的项目依旧是Eclipse项目,使用Android Studio可以直接导入并且转换为Android Studio的Android项目。

导出项目的时候在Scenes in build中把Unity程序的入口场景拖动到最上面,即下标为0的位置。

注意: Unity3D导出项目的时候要记得导出Android版本为4.0以上,不然Android兼容性问题很麻烦

现在,使用Android Studio导入刚才导出的项目。

  1. 新建一个Activity
  2. 修改Activity的父类为UnityPlayerActivityUnityPlayerActivity是Unity导出的Android项目的默认程序入口。
  3. 删掉新建的Activity的setContentView(xxx)方法,使其默认调用父类的方法,否则不会显示Unity的界面。而是显示的新建的Activity使用的布局。
  4. 修改Android项目的Manifests文件,将新建的Activity修改为默认程序入口。

    //Android的知识哦
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  5. 在新的Activity中编写要被调用的函数。即上面的onCall(String str)

    public void onCall(final String s){
       runOnUiThread(new Runnable() {//Android的UI操作必须发生在MainThread,其他操作不需要包到runOnUiThread里面
           @Override
           public void run() {
               Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
           }
       });
    }
  6. 编译,运行。

以上是Unity调用Android的void xxx(String s)类型的方法,调用其他函数,比如静态的,多个参数的,返回值不是void的函数,请参考下面的文档。


参考