寫給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新的物件就不再詳述了,無非就是用泛型實現物件內呼叫其他物件方法,相信大家都能看懂
相關文章
- Phaser遊戲框架與HTML Dom元素之間的通訊互動遊戲框架HTML
- Flutter與android之間的通訊FlutterAndroid
- 寫給go開發者的gRPC教程-通訊模式GoRPC模式
- Android開發中Gradle外掛,Gradle版本與JDK版本之間的對應關係 AndroidAndroidGradleJDK
- React Native與Android通訊互動React NativeAndroid
- Android開發之執行緒間通訊Android執行緒
- Flutter混合開發(三):Android與Flutter之間通訊詳細指南FlutterAndroid
- 一篇看懂Android與Flutter之間的通訊AndroidFlutter
- chrome瀏覽器外掛/擴充套件開發之popup與background通訊Chrome瀏覽器套件
- 移動端小白,30天掌握Flutter雙端外掛開發-中(Android篇)FlutterAndroid
- Android 程式之間通訊Android
- vue 外掛開發教程與釋出Vue
- Vue元件之間的資料傳遞(通訊、互動)詳解Vue元件
- Javascript與Python之間的程序間通訊JavaScriptPython
- web與APP之間的互動—WebViewJavascriptBridgeAPPWebViewJavaScript
- eslint外掛開發教程EsLint
- Maven外掛開發教程Maven
- Chrome外掛開發教程Chrome
- android 基於dex的外掛化開發Android
- Android與Flutter混合開發-UI互動AndroidFlutterUI
- Android外掛化技術之旅 1 開篇 - 實現啟動外掛與呼叫外掛中的Activity和ServiceAndroid
- 寫給小白的地理資訊的表示法:GeoJSONJSON
- H5與APP混合開發通訊互動記錄H5APP
- 寫給小白的音訊認識基礎音訊
- Flutter外掛開發---Android篇FlutterAndroid
- Flutter 與 Android 的互動FlutterAndroid
- 寫給小白的開源編譯器編譯
- swift之與h5之間的互動(一)SwiftH5
- 【Unity + Google Cardboard】 VR環境配置UnityGoVR
- Android Studio 讓開發效率事半功倍的外掛整理Android
- Flutter外掛開發指南01: 通道Channel的編寫與實現Flutter
- 外媒:遊戲開發者與貓咪互動對工作有益遊戲開發
- 寫給 Android 開發者的 Gradle 系列(三)撰寫 pluginAndroidGradlePlugin
- 寫給 Android 開發者的 Gradle 系列(二)撰寫 taskAndroidGradle
- PHP外掛系統的實現(五):觸發外掛PHP
- YonBuilder移動開發-移動原生外掛開發環境配置教程UI移動開發開發環境
- 自己動手編寫一個Mybatis外掛:Mybatis脫敏外掛MyBatis
- 寫給小白的 Nginx 文章Nginx
- Android 整合 Flutter 及通訊互動詳解AndroidFlutter