大致步驟如下:
1.創建新的 Android Studio 工程
2.為此 Android Studio 工程創建 Android Library 類庫(也就是一個 Module)(后面就是用它生成 jar)
3.生成 Jar
4.將 jar 導入 Unity 工程中的 Assets/Plugins/Android/
5.使用 AndroidJavaObject.Call 等方式調用
創建新的 Android Studio 工程#
1. 設置好 名稱 、 路徑 、 包名
這里的 Package name 只是這個 Android Studio 工程的包名,而我們需要的并不是這個工程,我們后面會在這個工程內新建一個 Android Library 類庫,這個類庫才是我們要導出 Jar 的對象。所以,這個 Android Studio 工程的 Application name 、Company Domain 、Package name 這三個參數可以隨意填寫,并不需要與正式工程相同。
2. 選擇 SDK 版本
這里的意思是選擇一個可兼容的最低的 Android 系統版本。自行選擇,隨意。
3. 選擇 Empty Activity
直接選擇空的 Activity 就可以了,因為這個是本工程的 Activity,并不是我們要導出的 Jar 的 Activity。
4. 給此 Activity 定義參數
同樣,因為這個是本工程的 Activity,并不是我們要導出的 Jar 的 Activity。所以隨意填寫,和要導出的 Jar 無關。
5. 新建 Module
6. 選擇 Android Library
7. 輸入 Module 的參數
這里的參數就是要導出 jar 的 Android Library 類庫參數。Package name 與正式工程一致。 Application/Library name 就是就填你要導出的 jar 插件的名稱。Module name 自動填寫就不用管了。
8.找到 Unity 中的 classes.jar 導入到這個 Module 的 libs 中。classes.jar 在安裝路徑的相對路徑如下:
\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
(Project 視圖下可以看到 libs 文件夾)
9.把 classes.jar 加入依賴。點擊 File->Project Structure
Modules 選擇自己新建的 Android Library,中間欄點 Dependencies 標簽,然后點擊右側加號+,選擇 File Dependency,然后找到自己拷貝進來的在 libs 目錄下的 classes.jar 點擊OK
9.給 Module 添加 Activity Class
給新建的 Class 命名。輸入 Name 然后點擊 OK。
package com.example.myjar;
import android.content.Intent;
import android.os.Bundle;
import com.unity3d.player.UnityPlayerActivity;
public class MyActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
public void ShareText(String message, String body) {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, message);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
}
10. 修改 build.gradle
雙擊 build.gradle,修改代碼,注意修改的是自己新建的 Library 的build.gradle,不是整個 project 的 build.gradle
在 build.gradle 末尾添加以下代碼,表示添加了一個 Task 任務
//task to delete the old jar
task deleteOldJar(type: Delete) {
delete 'release/AndroidPlugin.jar'
}
//task to export contents as jar
task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
///Rename the jar
rename('classes.jar', 'AndroidPlugin.jar')
}
exportJar.dependsOn(deleteOldJar, build)
11. 刷新 gradle
一般情況下修改了 build.gradle 后,系統上方會讓你 SyncNow,還可以手動刷新一下,右側點擊 Gradle 標簽,選中自己的 Library,右擊選擇Refresh external project
12. 生成 Jar
在上一步的窗口中(Gradle projects窗口)往下翻,可以在自己的 Library 展開項的 other 的展開項中找到 exportJar ,雙擊,然后等待完成。
然后就可以在 release 目錄下面找到生成好的 jar 包了,右擊這個 jar 包選擇 Show in Explorer 就可以拿到這個 jar 包了。
13. 導入 Unity
將拿到的 jar 放到 unity 工程的 Asset/Plugins/Android/ 目錄下。沒有的話就手動創建目錄。
**14. 修改或添加 AndroidManifest.xml **
**(重要,請仔細閱讀,真正理解 AndroidManifest 才是最快的方式) **
如果你是新工程,沒有使用過其他 android 的 sdk(指的是 unity 的插件),應該是沒有AndroidManifest.xml文件的,這樣可以在 Asset/Plugins/Android/ 目錄下新建一個 AndroidManifest.xml。
先介紹新加一個 AndroidManifest.xml
**需要注意 **的就是主 activity 的 android:name 需要為 用于導出 jar 的 Library 的包名 + 我們導出的 jar 的主類名(就像下方第4行:"com.example.myjar.MyActivity")(這個包名,其實也就是 unity 工程 Player Settings 中填寫的包名,因為他們需要一致)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:name="com.example.myjar.MyActivity"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
修改 AndroidManifest.xml
如果你之前的工程有使用過其他的 Android 的 SDK(指的是 unity 的插件),那么在 Asset/Plugins/Android/ 目錄下應該已經有一個 AndroidManifest.xml,那么你就需要將這次導出的 jar 的 activity 添加到這個 AndroidManifest.xml 中進行注冊。
一個 AndroidManifest.xml 只有一個主 activity (直接的觀察就是這個 activity 標簽中包含了下面這段標簽)。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
(這里需要強調一下,本文是基于 unity 的 Android 平臺的)
而 unity 工程,需要將繼承了 UnityPlayerActivity 或者 UnityNativePlayerActivity 的 Activity (見上面第9步)為啟動 Activity ,才可以在 Android 平臺(說白了就是手機等等)啟動你的 unity 工程。而這個 “設置為啟動 Activity ” 的步驟,就是在 AndroidManifest.xml 中完成的,也就是在 AndroidManifest.xml 中將這個 Activity 注冊為主 Activity 。
還有,你在 unity 中做的所有東西,發布到 Android 上,就只有一個 Activity,你如果在 unity 中喚起了其他的 Activity,就會像手機后臺切應用一樣的切換到你喚起的這個 Activity。所以,進行 unity 的 android 插件開發,只有一個入口,也就是繼承 UnityPlayerActivity 或者 UnityNativePlayerActivity (UnityNativePlayerActivity 其實就是繼承UnityPlayerActivity 的一個類,并沒有進行任何操作)。
理解了這些之后,就能理解為什么一般的 unity 插件,并不會將自己的 Activity 注冊成主 Activity,所以你只需要將他們的 Activity 標簽復制粘貼到你的 AndroidManifest.xml(Asset/Plugins/Android/ 目錄下,一個工程只需要一個 AndroidManifest.xml(多個的用法本文不涉及,你只需要知道,Asset/Plugins/Android/ 目錄下僅有一個 AndroidManifest.xml 文件))中就可以了(如果他們的 Activity 標簽有上面提到的 “intent-filter” 標簽 也就是被標記成主 Activity,你就要考慮,他們的功能是需要在 unity 的這個主 Activity 啟動就響應的,還是切換另外一個 Activity 才進行操作的)。
所以,綜上,如果是你自行開發的多個 unity Android 插件(jar),就需要盡量先在 Android 層合并成一個 jar 插件包,以保證只有一個入口,一個主 Activity 。不光是自行開發的,使用其他 sdk 的時候,也要想,如果可以直接在 Android 層進行合并操作(統一一個 Activity 入口,然后所有調用其他 sdk 功能的接口全部放在這個 Activity 中)的,就盡量在 Android 層進行。
多個 unity Android 插件(jar)合并的時候,難的部分其實也不難,就是理解他們的功能,然后合并 AndroidManifest.xml 的操作。
(下次我會介紹一些特殊情況,比如如何合并 Vuforia 的 AR SDK 和 其他 SDK 插件)
15.調用 jar 插件中的接口
unity 中調用 android 層的接口基本都是通過 AndroidJavaClass 、AndroidJavaObject 的方式。
比如,上面我導出的 jar 插件中,在 MyActivity 類中我寫了一個 ShareText(String , String ) 的接口(第9步),那么我在 unity 中就可以通過以下代碼調用這個接口。
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
string message = "this is my title";
string body = "this is my content";
jo.Call("ShareText", message, body);
如果你需要喚起其他的 Activity,就在上方第二行,將 "currentActivity" 改成你在 AndroidManifest.xml 中注冊的 Activity 名字,然后就可以通過 AndroidJavaObject.Call 的方式調用那個 Activity 類里的接口。如果這個接口在這個 Activity 類里被標記成了 static,還可以通過AndroidJavaObject.CallStatic 的方式調用。
第一行的 "com.unity3d.player.UnityPlayer" 是需要調用的接口所在的 Activity 所在的包名,如果是 unity 主 Activity ,就可以直接使用 "com.unity3d.player.UnityPlayer",如果是其他插件包,就使用那個包的包名。
16. 效果