1. 程式人生 > >Unity使用NDK在Android平臺上引用C++程式碼的so檔案(上)

Unity使用NDK在Android平臺上引用C++程式碼的so檔案(上)

這是我的第一篇博文,在我剛開始實現本文功能是的,感悟真的是挺深的,為了給大家分享我的探索經驗也為了以後自己方便查閱,寫下此篇博文

學習一種新的東西,一定要從最簡單的開始,把一切需要實現的功能做到最容易實現的地步,比如說引用外部一個方法,就要把這個方法做到最簡單,比如說這個方法沒有引數只是返回一個int型別的數字,而不是傳入一個string或者是一個數組,只有這樣才能避免了由於語言之間的差異性而產生的錯誤,這樣在你不瞭解這個東西的時候,你不知錯誤到底出現在什麼地方,當你把最簡單的東西完成了,這時候你可以自己探索更復雜的東西了。

切入正題之前我所說的這些,在我看來也是以後學習少走彎路的實用方法。

我把這篇文章的知識分成幾個部分:

一、原理(unity專案中是如何讓Android呼叫C++程式碼)

unity專案打包成apk後其實就相當於一個Android原生的專案比如說有AndroidManifest.xml、res、lib等檔案或資料夾,只是unity把遊戲封裝在一個繼承Activity類的UnityPlayerActivity的類中啟動的。Android專案中呼叫C++程式碼使用的是so檔案的方式,並把so檔案放入libs資料夾下面直接就可以在程式碼中引用。同樣我們要在unity專案中植入一個Android的外掛,實現的功能就是把外掛中的Android專案的Activity同unity中的專案中的Activity合併為一個Activity,實現unity專案中有Android專案中的功能。完成這個以後,在unity專案中就可以引用so檔案了

二、製作unity專案中的Android外掛

我使用的是eclipse,用as也是相同的原理

1.首先建立一個Android的專案


包名要和unity專案中的包名相同,這樣生成的外掛才能保證兩個activity可以合併在一起,專案的sdk版本最好設定在14以上,否則製作的外掛要攜帶一個相容包。下一步

到這要把圖片中箭頭所指的地方勾選上,這樣unity才可以引用這個外掛,剩下的可以一直next下去完成。

2.新增unity引擎中的classes.jar的包引用位置在unity引擎的安裝目錄下(D:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes

)的下面,把他複製到Android專案中的libs資料夾下面

重新整理一下是這樣的

然後右鍵classes.jar選擇Build Path讓後選擇Add to Build Path專案中出現

這些步驟的目的是可以在專案中繼承unity中的UnityPlayerActivity類

3.改寫MainActivity中的程式碼


改好後是這樣的

package com.rxjian.sdktest;

import com.unity3d.player.UnityPlayerActivity;

import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    //這是用來測試使用的方法,就是彈出一個提示
    public void MyToast(String str) {
		Toast.makeText(this,str, Toast.LENGTH_SHORT).show();
	}
}

Android專案的檔案到此就修改好了,接下來把它匯出成一個jar檔案,右鍵eclipse中的該專案選擇Export

彈出如下視窗

其中如果以後我們需要用到res中的檔案我們一可以勾選上,但是為了最簡單的學會本文的內容,我們還是採用最簡單的方式,這樣可以減少錯誤的可能。

我們製作的外掛包名叫sdk.jar,上圖可以看到。

接下來我問要修改一下AndroidManifest.xml檔案,目的是來設定安裝程式的資訊,原檔案中是這樣:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.rxjian.sdktest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.rxjian.sdktest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

我們可以刪除一些沒有必要的檔案內容,之前我們匯出檔案包的時候沒有選擇res資料夾,所以其中對res資料夾裡東西的引用也要改掉比如

@string/app_name
最後我們改成了這樣
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.rxjian.sdktest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <application>
        <activity
            android:name="com.rxjian.sdktest.MainActivity" 
			android:label="sdktest">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


至此我們的Android外掛基本製作完成。

三、unity專案中植入外掛

新建一個unity專案,看下圖簡歷資料夾的目錄

把製作的jar包和AndroidManifest.xml放入Android資料夾下面,最後下樣子如下:

外掛就這麼簡單的完成了,接下來我們測試一下

四、測試外掛

在unity場景中新建一個button和一個test的C#指令碼

指令碼中這樣寫

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

public class test : MonoBehaviour {
	public Button btn;
	private AndroidJavaClass _jc;
	private AndroidJavaObject _jo;

	// Use this for initialization
	void Start () {
		_jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		_jo = _jc.GetStatic<AndroidJavaObject> ("currentActivity");
		btn.onClick.AddListener (onclick);    //新增按鈕監聽
	}
	
        //按鈕監聽的方法
	private void onclick(){
		_jo.Call ("MyToast","呼叫成功");    //呼叫之前的MainActivity中的MyToast方法彈出一個Toast
	}
}

我們把指令碼新增到Canvas上,把Button物件拖到指令碼上面的btn上如圖:

然後打包成apk

生成檔案後放在Android模擬器或手機上執行


至此所有的已經做好,到了這一步你可以自己修改其中的東西去發掘更多的奧祕。

結束語

外掛是已經制作好了,關於如何呼叫so檔案以及如何編寫和製作,請關注我的下一篇博文

Unity使用NDK在Android平臺上引用C++程式碼的so檔案(下)

相關推薦

Unity使用NDK在Android平臺引用C++程式碼so檔案

由於最近進入了公司,手頭上的工作需要一點一點的去適應,所以沒有空來完成接下來的博文,今天突然想到寫一些,發現這麼久沒有接觸了,好像已經忘記了很多,寫下這個博文,我也正好回顧一個這一方面的知識。 關於在unity上使用C++的程式碼需要用到SO檔案了,這就像Cocos上使用C

Unity使用NDK在Android平臺引用C++程式碼so檔案

這是我的第一篇博文,在我剛開始實現本文功能是的,感悟真的是挺深的,為了給大家分享我的探索經驗也為了以後自己方便查閱,寫下此篇博文學習一種新的東西,一定要從最簡單的開始,把一切需要實現的功能做到最容易實現的地步,比如說引用外部一個方法,就要把這個方法做到最簡單,比如說這個方法沒

android studio ndk-build 編譯C生成.so檔案ndk基礎篇

一、概要 最近專案需要,要把程式碼中加密的部分打包成so檔案,剛開始接觸的時候真是痛苦呀,網上好多資料,都不是很詳細,步驟也不清晰,所以我整理了一下,希望大家喜歡。 現在android studio打包so檔案有兩種方式,第一種是ndk-build編譯專案,還有一種用

c#操作壓縮檔案ICSharpCode

 網上轉過來的,經測試很好用。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; usin

phpcms v9 表單新增檔案傳欄位單個檔案downfile

$string .= $str."<input type='text' name='info[$field]' id='$field' value='$value' class='input-text' style='width:80%'  readonly='readonly' />  <

C程式碼實現從FTP下載檔案

從FTP上下載檔案這個功能我早就想實現了,但是苦於百度的文章大多是下載連結,一直沒捨得積分下載,這次通過查閱MSDN,將一套下載流程函式摸了一下,寫出程式碼實現從FTP下載檔案 環境 VS2015 程式碼: #include <iostream> #include <

C#實現FTP檔案傳、下載功能、新建目錄以及檔案的刪除

轉載至:https://www.cnblogs.com/zhenzaizai/p/7434669.html using  System; using  System.Collections.Generic;

android studio編譯c生成.so檔案

今天練習了用studio編譯c生成.so檔案。 一、首先是配置NDK(以下是以我自己的路徑為例) 二、環境的搭建 設定ndk路徑 成功之後我們可以在local.properties檔案中看到:

使用NDK編譯C/C++為.so檔案

概述: Android NDK是一系列工具的集合。幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。NDK集成了交叉編譯器,並提供了相應的mk檔案隔離平臺、CPU

android studio 編譯C生成.so檔案出現java.lang.UnsatisfiedLinkError

參考文章:http://www.2cto.com/kf/201607/526887.html 這篇文章作者講得很好了,但是我照著做的時候還是不能正常執行程式,總是報java.lang.UnsatisfiedLinkError,其實就是couldn't find "libhuazict.so"

android執行C++程式碼中的 time(NULL)獲取當前時間戳,為什麼得到的結果不對

如題,用NDK執行C++程式碼中time(NULL)函式,得到的結果不對,這是為什麼呀?? time_t current_time = time(NULL)*1000; CLog::Log(LOGDEBUG, "%ll

即時通訊開發平臺的部分C#程式碼

using System;   using System.Text;   using System.Runtime.InteropServices;     namespace Platform   {       /**********************

C#中用ILMerge將所有引用的DLL和exe檔案打成一個exe檔案圖解

今天做了一個軟體,想釋出的時候才發現呼叫的類沒幾個,就像把它們都跟EXE檔案打包在一起,以後複製去別的地方用也方便,於是上網搜了一下,發現網上大部分都是用ILMerge實現的,於是也自己試了一下,不過網上都沒有詳細的步驟演示,我就花點時間做了個教程,方便以後再有人想

Android Studio2.2.3使用C++生成so檔案

  之前的時候寫過Android Studio2.2.3之前的so庫檔案,之前的版本的so庫檔案的編寫詳見,之前寫過的文章: http://blog.csdn.net/wb175208/article/details/52577167 當再次使用的時候,

如何理解c++叠代器

stl源碼 str 抽象 ice ive 左值 arc 統一 為什麽 1、如何理解叠代器?叠代器不是指針,也似乎不是string這種類型 參考:叠代器與指針的區別是? C++map叠代器的++操作是如何實現的?討論。iterator提供了遍歷STL容器裏元素的方式,not-

C#復習筆記4--C#3:革新寫代碼的方式查詢表達式和LINQ to object

類型 否則 表達 數據集 clas 階段 邏輯 變量 RR 查詢表達式和LINQ to object(上) 本章內容: 流式處理數據和延遲執行序列 標準查詢操作符和查詢表達式轉換 範圍變量和透明標識符 投影、過濾和排序 聯接和分組 選擇要使用的語法 LINQ中的概

《effective c++》讀書筆記

作用 成員 了解 static 左值 section 構造 單純 fec 最近在讀《Effective C++》,確實是經典之作,但是有的條款也需要一些細節補充,所以都列在這篇文章裏,希望能不斷更新,個人閱讀的是第三版,不包括C++ 11的內容。 條款1:視C++為一個語言

C# List 賦值 --引用類型的賦值和復制

地址 修改 引用 進行 urn ont pre 詳細 理論 最近項目維護中遇到一個問題,確切的說應該是兩個月前的問題也是因為這裏引起的,可惜當時困於業務不熟悉,也沒有更多時間允許查詢根源,導致再次引發了新的問題!!! 問題場景:基礎數據存於List類型的BOMs中,計算過程

caffe - windows配置 C++ 開發環境 & ubuntu安裝其它深度學習框架

過程 ubuntu 解決方案 ubun 核心 conda pytho 配置 caff windows 上配置C++開發環境的過程: ubuntu上配置caffe、tensorflow、mxnet的過程 基於 anaconda2 1、caffe pip不是

springboot/springmvc檔案CommonsMultipartResolver

上一篇博文講到了(Servlet3.0支援)的檔案上傳:https://blog.csdn.net/frozenpower/article/details/81141297 這篇我們來看可配置的檔案上傳解析器CommonsMultipartResolver CommonsMultipartR