寫給VR手遊開發小白的教程:(五)Cardboard外掛與Android之間的通訊互動
原文地址:http://blog.csdn.net/mao_xiao_feng/article/details/52416439
上篇已經把BaseVRDevice這個類解析了一下,緊接著,擺在我們眼前的問題是既然已經完成了VR裝置的基類,那後續的子類必然會對基類做一個相應的擴充套件,以實現Android和iOS裝置所獨有的功能。事實上AndroidBaseVRDevice這個類就完成了這些事情,學過android的人都知道一個app的執行最基本的就是Layout和Activity,一個控制前端一個控制後臺,而我們本節所要介紹的這個類,就是在BaseVRDevice的基礎上,增加了Android所特有的Java物件的建立和Activity的管理,這搭建了一個橋樑,允許我們將Unity和Android兩個不同的平臺進行通訊和互動。
AndroidBaseVRDevice.cs的程式碼如下,大家可以參照著看看
#if UNITY_ANDROID
using UnityEngine;
using System.Collections.Generic;
public abstract class AndroidBaseVRDevice : BaseVRDevice {
protected AndroidJavaObject cardboardActivity;
public override bool SupportsNativeDistortionCorrection(List<string> diagnostics) {
bool support = base.SupportsNativeDistortionCorrection(diagnostics);
if (cardboardActivity == null) {
diagnostics.Add("Cannot access Activity");
}
return support;
}
public override void Destroy() {
if (cardboardActivity != null) {
cardboardActivity.Dispose();
cardboardActivity = null;
}
base.Destroy();
}
protected virtual void ConnectToActivity() {
try {
using (AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
cardboardActivity = player.GetStatic<AndroidJavaObject>("currentActivity");
}
} catch (AndroidJavaException e) {
cardboardActivity = null;
Debug.LogError("Exception while connecting to the Activity: " + e);
}
}
protected virtual bool CallActivityMethod(string name, params object[] args) {
return CallObjectMethod(cardboardActivity, name, args);
}
protected virtual bool CallActivityMethod<T>(ref T result, string name, params object[] args) {
return CallObjectMethod(ref result, cardboardActivity, name, args);
}
protected AndroidJavaObject Create(string className, params object[] args) {
try {
return new AndroidJavaObject(className, args);
} catch (AndroidJavaException e) {
Debug.LogError("Exception creating object " + className + ": " + e);
return null;
}
}
protected static bool CallObjectMethod(AndroidJavaObject jo, string name, params object[] args) {
if (jo == null) {
Debug.LogError("Object is null when calling method " + name);
return false;
}
try {
jo.Call(name, args);
return true;
} catch (AndroidJavaException e) {
Debug.LogError("Exception calling method " + name + ": " + e);
return false;
}
}
protected static bool CallObjectMethod<T>(ref T result, AndroidJavaObject jo, string name,
params object[] args) {
if (jo == null) {
Debug.LogError("Object is null when calling method " + name);
return false;
}
try {
result = jo.Call<T>(name, args);
return true;
} catch (AndroidJavaException e) {
Debug.LogError("Exception calling method " + name + ": " + e);
return false;
}
}
}
#endif
來自CODE的程式碼片AndroidBaseVRDevice.cs
/**************************************************************************************************************************************/
程式碼的第一句就給我們擺了難題,AndroidJavaObject這個類看著像是Android的,但事實上它是Unity庫裡的一個類,見聖典:
http://www.ceeger.com/Script/AndroidJavaObject/AndroidJavaObject.html
發現這個類下,有一系列函式和一個構造方法static function AndroidJavaObject (className : string, params args : object[])
這個構造方法很有趣,它有兩個引數分別是1、指定的Java類名2、傳遞的引數
為什麼說他有趣?
大家可以看一個例子
//建立一個java.lang.String物件,持有該字串"some string"function Start() {var jo = new AndroidJavaObject("java.lang.String", "some string");}
這是摘自聖典的一個例子,我們通過建構函式將AndroidJavaObject例項化了以後,生成的居然不是AndroidJavaObject的例項而是其字串引數java.lang.String物件的一個例項。這很神奇,因為我們通常所能認識到的是建構函式構造的一定是類本身,那為什麼這裡不是?
事實上,我們構造出來的仍然是本身,只不過“看起來”不一樣而已。什麼是“看起來”不一樣呢?
從這裡需要引申到Java中所有物件的祖先類,Object類,這裡的AndroidJavaObject就是Object類的一個泛型,關於Object類的概念,給一個連結這裡不再詳述
http://www.cnblogs.com/mengdd/archive/2013/01/03/2842809.html
好了,現在Object作為泛型類,把AndroidJavaObject這個類作為引數來確定具體例項化哪個物件,而例項化哪個物件的問題,就由例項化的AndroidJavaObject類來解答了,所以說,不管是最終例項化的java.lang.String類,還是我們覺得應該例項化的AndroidJavaObject類,都是產自於Object類,它們事實上來源是相同的,而我們只是通過泛型這種手段來將Object物件做了個“變形”。
理解了這一步,我們就知道AndroidJavaObject類在Unity中存在的意義了,它就像一座橋樑,將Java物件與遠方的Unity中的物件聯絡起來。
/**************************************************************************************************************************************/
AndroidJavaClass player = new AndroidJavaClass("com.Unity3D.player.UnityPlayer"
//同理AndroidJavaClass也是如此,只不過它聯絡了Java中的類和Unity中的類。需要說明的一點是,Class類沒有公共構造方法,我們都知道類是物件的抽象,而Class是對Java中所有類的一個抽象,它儲存的是一個Java類的元資訊,負責類的型別標識問題而從不負責類的例項化問題。於是,我們知道AndroidJavaClass的例項得到的是指定的型別,而不是例項化的物件。附上聖典的介紹:
http://www.ceeger.com/Script/AndroidJavaClass/AndroidJavaClass.html
/**************************************************************************************************************************************/
解決了這個問題,讓我們接著往下
using (AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
//這一步相當於在Java中引用了名為com.unity3d.player.UnityPlayer的庫,而C#與Java互通上面已經說了,一句話就是C#中建立的Java物件需要用到新增到Java語言中的com.unity3d.player.UnityPlayer庫中的操作,聽起來有些拗口。
cardboardActivity = player.GetStatic<AndroidJavaObject>("currentActivity");
//然後我們接著呼叫AndroidJavaClass 類下的GetStatic.<FieldType>方法去獲取當前的Activity,這句話如果在上一句之前是無法執行的,因為GetStatic.<FieldType>語句是Unity庫裡的語句,我們正是通過新增了com.unity3d.player.UnityPlayer庫才使得該語句可用。說到這裡又有人會問了,我們開頭的using UnityEngine不是已經將Unity庫匯入進來了嗎?其實using UnityEngine只是將Unity和C#聯絡起來,但是我們現在做的,是C#環境中,實現Android和Unity的通訊,兩者顯然不一樣。
哈哈,這就是程式設計的魅力:無限的擴充套件性+嚴密的邏輯性!
/**************************************************************************************************************************************/
接下去呼叫物件方法的一些函式和Creat新的物件就不再詳述了,無非就是用泛型實現物件內呼叫其他物件方法,相信大家都能看懂
相關文章
- 寫給VR手遊開發小白的教程:(四)補充篇,詳細介紹Unity中相機的投影矩陣VRUnity矩陣
- Phaser遊戲框架與HTML Dom元素之間的通訊互動遊戲框架HTML
- Flutter與android之間的通訊FlutterAndroid
- 搭建CARDBOARD+ANDROID+unity3d的VR開發環境AndroidUnity3DVR開發環境
- Android開發之執行緒間通訊Android執行緒
- VR開發--Cardboard專案三:通過外接裝置控制視野移動VR
- React Native與Android通訊互動React NativeAndroid
- Android Studio Plugin 外掛開發教程(一) —— 開發你的第一個外掛AndroidPlugin
- 寫給iOS小白的MVVM教程(序)iOSMVVM
- 擁抱 Android Studio 之五:Gradle 外掛開發AndroidGradle
- Android 之 Binder與程式間通訊Android
- Android混合開發之WebView與Javascript互動AndroidWebViewJavaScript
- 寫給go開發者的gRPC教程-通訊模式GoRPC模式
- Flutter混合開發(三):Android與Flutter之間通訊詳細指南FlutterAndroid
- vue 外掛開發教程與釋出Vue
- Vue元件之間的資料傳遞(通訊、互動)詳解Vue元件
- 一篇看懂Android與Flutter之間的通訊AndroidFlutter
- 安卓開發之Fragment的使用與通訊安卓Fragment
- H5與APP混合開發通訊互動記錄H5APP
- 移動端小白,30天掌握Flutter雙端外掛開發-中(Android篇)FlutterAndroid
- Android Studio Plugin 外掛開發教程(二) —— 外掛SDK中的常用物件介紹AndroidPlugin物件
- Maven外掛開發教程Maven
- Chrome外掛開發教程Chrome
- Stylus外掛開發教程
- 寫給小白的音訊認識基礎音訊
- Android Studio Plugin 外掛開發教程(四) —— 為自動生成資料庫程式碼的外掛新增UIAndroidPlugin資料庫UI
- Android 程式之間通訊Android
- Android Studio Plugin 外掛開發教程(三) —— 製作一個自動生成資料庫程式碼的外掛AndroidPlugin資料庫
- Android和H5之間的互動AndroidH5
- 寫給小白的開源編譯器編譯
- web與APP之間的互動—WebViewJavascriptBridgeAPPWebViewJavaScript
- eslint外掛開發教程EsLint
- YonBuilder移動開發-移動原生外掛開發環境配置教程UI移動開發開發環境
- Discuz 外掛開發視訊
- WordPress外掛開發例項教程 - 版權外掛
- swift之與h5之間的互動(一)SwiftH5
- Flutter外掛開發指南01: 通道Channel的編寫與實現Flutter
- Android與Flutter混合開發-UI互動AndroidFlutterUI