Unity with the simple realization [Android] 01-Unity and interactive communication of Android

Foreword

Unity also use for some time, and Andrews also played a lot of packages, but for Unity and Android interactions is poorly understood.

Because of work requirements, we need to take some of the sdk Android platform (extensions). I would like to take this opportunity to learn some knowledge under Unity interact with Android, and made a simple realization.

Implementation steps will now be recorded for future reference.

First, the development ready

Unity, Android Stuido and JDK installation, these are the basic operations, and there are many online tutorials, do not dwell on here.

The development of the software version used is as follows:

Android Studio 3.5

Unity 2018.3.10f1

Java 1.8.0191

 

Second, to achieve the function

To Andrews extensions in unity project, there are two ways:

1, Unity for Android export project engineering, then Android Studio (hereinafter referred to as AS secondary development), add extensions. In such a way to develop it is very flexible and also very easy to change, but it is very troublesome, because every time a change to be played back to Andrews project.

2, the extension made into Android library (jar package), and then introduced into the jar package Unity used directly. In this way, users can not modify the function of this library, but also easier to use.

 

Because I will do function may spread use in the team, we do not need everyone to do the changes. So choose the second way.

So the purpose of this paper is:

Android make a library file (jar package), and then use it in Unity.

Third, how to make Android libraries

1, the new Android project

 Open AS, a new Android project, select Empty Activity, configure the project name, package name, location and language, as shown below

 Choose the best language Java, because Java and C # syntax is very similar to learning cost is very low.

 

After the project is created, the default display is the next Android app view engineering structures, as shown below. MainActivity.java can see a file name in the package, this is the Android app of the entrance, but there are not going to use it, can be ignored.

 

2. Create an Android Library module

 Select the app, then right click, select Module, select Create New Module window  Android Library 

 

 After fill in the Library name, Module name, Package name, and Language, point to complete.

 Here Package name seems to be changed, and do not have exactly the same as before when you create a project (not verified). But to something less, or to keeping it.

 

 Now you can see, there is at the same time the app and mysdk module in the project, Talia is there same level, and has its own source directory (com.letui.mysdk), and a list of directories (manifests).

 app portion can not control, only mysdk subsequent module is operating.

 

 3, the introduction of Unity docking Android libraries 

  1) in the installation directory under parts of unity, find a file named classes.jar of

  My directory D: \ Unity2018 \ Editor \ Data \ PlaybackEngines \ AndroidPlayer \ Variations \ mono \ Development \ Classes

  2) Then the paste to classes.jar mysdk libs directory module (handover needs to project to the project view)

  Additional description:

  In il2cpp directory also has the same name classes.jar a file, its directory

   D:\Unity2018\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes

  这两个文件的选择,与unity的Player Setting中脚本后端设置有关。如下图

  

    脚本后端用哪个就,就选哪个目录下的classes.jar

  3)选中刚粘贴的classes.jar文件,右键,选择 Add as Library,出现一个弹窗口,默认选中mysdk模块,直接点确定

  然后,这个classes.jar文件就被引入到工程中了,展开三角,可以看到如下三个模块,其中就有com.unity3d.player。如下

  

 4、创建本模块的Activity文件

  1)展开mysdk模块下的src目录,选中com.leitui.mysdk,然后右键,新建一个Activity,选择Empty Activity,输入Activity Name以及Package Name和Language,勾掉Generate Layout File, 完成。

 

 新建的SDKMainAcivity.java脚本,默认继承自AppCompatActivity,并带有一个onCreate方法,如下:

 

现将SDKMainActivity脚本内容修改为继续自UnityPlayerActivity ,并添加两个方法 UnityCallAndroid 和 AndroidCallUnity

UnityCallAndroid 用来接受Unity的调用,AndroidCallUnity用于向unity发起调用。具体代码如下:

 1 package com.letui.mysdk;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 
 5 import android.os.Bundle;
 6 import android.widget.Toast;
 7 
 8 import com.unity3d.player.UnityPlayer;
 9 import com.unity3d.player.UnityPlayerActivity;
10 
11 public class SDKMainActivity extends UnityPlayerActivity {
12 
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16     }
17 
18     //unity调用Android
19     public void UnityCallAndroid () {
20 
21         Toast.makeText(this,"unity调用android成功", Toast.LENGTH_LONG).show();
22 
23         AndroidCallUnity();
24     }
25 
26     //android调用unity
27     public void AndroidCallUnity () {
28 
29         //第1个参数为Unity场景中用于接收android消息的对象名称
30         //第2个参数为对象上的脚本的一个成员方法名称(脚本名称不限制)
31         //第3个参数为unity方法的参数
32         UnityPlayer.UnitySendMessage("receiveObj", "UnityMethod", "This is args.");
33     }
34 }

 

5、将模块打包

  打包方法有两种。

  一是手动进行构建,然后在Build/intermediates/packaged-classes/release目录下找到相应的jar包(这个jar包默认名称为classes.jar,为了区分,需要自己改名称);

  二是用gradle命令。

  打开本模块的build.gradle文件,在文件尾添加如下的一组命令。

//----------------这是一组将module导出为jar的gradle命令-------------------
// mysdk为自定义的jar包名称
//task to delete the old jar
task deleteOldJar(type: Delete) {
    delete 'release/mysdk.jar'
}

//task to export contents as jar
task exportJar(type: Copy) {
    from('build/intermediates/packaged-classes/release/')
    into('release/')
    include('classes.jar')
    ///Rename the jar
    rename('classes.jar', 'mysdk.jar')
}

exportJar.dependsOn(deleteOldJar, build)
//---------------------------命令结束------------------------------

 这组命令的功能就是打包方法1的自动化版。

 build.gradle文件修改后,会提示要求同步,直接同步即可。同步结束,在IDE右上点开Gradle窗口,在other下找到exportJar命令。

 双击exportJar命令,等一会就会自动生成本模块的jar文件了。

生成的文件位于mysdk/release/目录下,如下图

 

6、修改AndroidManifest.xml文件
  1)打开本模块的AndroidManifest.xml文件,文件位于mysdk/src/main目录下,如下图:

  这个文件的内容,目前只有一对application标签和activity标签 

  删掉这三行,将其内容修改为如下: 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.letui.mysdk">
 4 
 5     <!-- 这个android:label设置后,unity中ProductName就不生效了,记得改这个-->
 6     <application android:label="MySDK">
 7 
 8         <!-- 这个android:name的值必须为包名+类名-->
 9         <activity android:name="com.letui.mysdk.SDKMainActivity">
10             <intent-filter>
11                 <action android:name="android.intent.action.MAIN" />
12                 <category android:name="android.intent.category.LAUNCHER" />
13             </intent-filter>
14 
15             <!-- 这一行不能少,否则会闪退-->
16             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
17         </activity>
18     </application>
19 
20 </manifest>

这其中有三个要注意的点,注释中都有说明。修改完成后保存。

至此,在AS中的操作就结束了。

 

四、在unity中使用jar文件

1、新建一个Unity工程。

  a.新建一个Unity工程,在Assets目录下新建Plugins/Android/bin目录。

  b.将第三步修改的AndroidManifest.xml文件拷贝到Assets/Plugins/Android目录下

  c.将第三步生成的mysdk.jar文件拷贝到Assets/Plugins/Android/bin目录下

  完成之后文件结构图如下:

    

  libs目录用于存放其它android插件的jar文件,没有也可以不用创建。

 

 2、制作一个UI界面

 a.在SampleScene场景中创建一个Canvas,并创建一个名为"receiveObj"的对象,在receiveObj之下再放一个按钮和一个Text。

 按钮用于触发调用Android方法。

 Text用于显示Android调用Unity方法传递来的参数。如下图:

 这里要注意,receiveObj的名称必须与SDKMainActivity类的AndroidCallUnity方法中的UnityPlayer.UnitySendMessage方法的第一个参数保持一致。

  

 b.创建一个SDKTest.cs文件,将脚本挂在receiveObj对象上。如下: 

 

SDKTest脚本的内容如下: 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SDKTest : MonoBehaviour
{
    private AndroidJavaClass jc;
    private AndroidJavaObject jo;

    private Button btn;
    private Text text;

    private void Awake()
    {
        btn = transform.Find("Button").GetComponent<Button>();
        text = transform.Find("Text").GetComponent<Text>();

        //这两行是固定写法
        jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        jo = jc.GetStatic<AndroidJavaObject>("currentActivity");

        btn.onClick.AddListener(OnBtnClickHandler);
    }

    private void OnBtnClickHandler ()
    {
        //调用Android中的方法UnityCallAndroid
        jo.Call("UnityCallAndroid");
    }

    /// <summary>
    ///  被Android中AndroidCallUnity调用
    /// </summary>
    /// <param name="str"></param>
    public void UnityMethod(string str)
    {
        Debug.Log("UnityMethod被调用,参数:" + str);
        text.text = str;
    }
}

 其中必须要有UnityMethod方法,因为它在AndroidCallUnity方法中的UnityPlayer.UnitySendMessage的第二个参数已经指定了。如果不存在的话,调用就会出错。

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

这两句,一个是获取到UnityPlayer类,一个是获取到类的实例。
到于为什么这样能取到我创建的模块的SDKMainActivity的实例,还有待探究。反正目前这么写了就行了。

 3、打包并测试。

  在unity中设置Bundle Identifier和Company等信息之后,打一个apk包。

  安装后运行,能正常显示UI。

  点击按钮后,显示了一个Toast,提示“Unity调用Android成功”,说明jar包中的UnityCallAndroid方法被调用。

  Unity->Android通信成功

  同时屏幕上方的NewText被变更为“This is args”,"This is args"是 AndroidCallUnity方法中传递给UnityMethod方法的参数。

  这表示Android->Unity通信成功

  演示见下图:

调用 前:,调用后: 

 

五、一点说明

1、模块的包名和Unity的Bundle Identifier可以不一致(至少在Module模式下,是可以不一致的)。

说明:写这条是因为其它相关文章全都要求两边保持一致,而如果模块的包名要跟着Unity工程走,也太蛋疼了,所以验证了下。

2、将AndroidManifest.xml引入到Unity之后,在unity中设置的Product Name就无效了。

需要在AndroidManifest.xml的application标签中,添加android:label属性来指定。

  

      初次接触Android开发,以上内容如有错误,还请不吝指出。

 

  本文件所使用的Android工程和Unity工程源码在此:安卓工程  Unity工程

Guess you like

Origin www.cnblogs.com/imteach/p/11567481.html