android studio | openGL es 3.0增強現實(AR)開發 (1) 建立一個openGL es 3.0開發環境
阿新 • • 發佈:2019-02-10
1.什麼是NDK,什麼是JNI?
NDK:Native Development Kit(原生開發工具包), NDK允許使用者使用類似C / C++之類的原生程式碼語言執行部分程式。它包括下面的部分(1)從C / C++生成原生程式碼庫所需要的工具和build files。(2)將一致的原生庫嵌入可以在Android裝置上部署的應用程式包檔案(application packages files ,即.apk檔案)中。(3)支援所有未來Android平臺的一系列原生系統標頭檔案和庫
優點:
- 程式碼的保護,由於apk的java層程式碼很容易被反編譯,而C/C++庫反匯難度較大。
- 在NDK中呼叫第三方C/C++庫,因為大部分的開源庫都是用C/C++程式碼編寫的。
- 便於移植,用C/C++寫的庫可以方便在其他的嵌入式平臺上再次使用。
JNI:Java Native Interface,(JNI)標準是java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行互動。JNI 是本地程式設計介面,它使得在 Java 虛擬機器 (VM) 內部執行的 Java 程式碼能夠與用其它程式語言(如 C、C++ 和組合語言)編寫的應用程式和庫進行互動操作。
隨意NDK和JNI和關係是:NDK是基於JAVA JNI技術所開發的一套應用於android程式設計的一系列工具集合。
2.檢查自己的IDE版本(最好用1.3之後的版本)和SDK,NDK版本,此處我這邊沒安裝NDK,下面想辦法安裝。
3.新建一個工程,配置裡面的NDK工程路徑
4.到這裡基本環境就搞定了,下面開始建立一個自己的新工程,用來做openGL es 3.0開發的第一步
配置檔案main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.dragon.opengles01.Main">
<TextView
android:id="@+id/ndk_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
建立如下目錄
NDKTest.java中程式碼如下
package com.dragon.opengles01.ndk;
/**
* This file created by dragon on 2016/7/31 0:25,
* belong to com.dragon.opengles01.ndk .
*/
public class NDKTest {
public native static String hello();
// 預設是NDK.moduleName
static {
System.loadLibrary("ndk_test");//此處是生成.so檔案
}
}
5.rebuild一下專案,會在debug目錄下生成NDKTest的.class檔案,如下所示
6.通過終端進入個目錄,用javah生成.h的標頭檔案
javah -jni com.draogn.opengles01.ndk.NDKTest
7.接下來在main目錄下面建一個jni目錄,在customize the activity選項卡下選擇 change folder location
8.將javah生成的.h標頭檔案拷貝或是剪下到jni目錄中去,然後在jni目錄下建立一個filename.cpp的C++檔案,其中filename的名子可以隨便取,一般是採用java+packageName+className這種方式
在C++檔案中敲入下面程式碼
#include "com_dragon_opengles01_ndk_NDKTest.h"
#include <string.h>
JNIEXPORT jstring JNICALL Java_com_dragon_opengles01_ndk_NDKTest_hello
(JNIEnv *env, jobject obj)
{
return env->NewStringUTF("我是來自NDK的C++");
}
9 build->Rebuild Project,如果有下面的錯誤
是因為你先操作的終端沒退出來有兩種解決辦法1.你敲回原工程路徑,如本人的如下
2.另一種方式是重啟IDE,這樣你再整的時候就可以了
10,然後重啟Rebuild一下,席八,又出紅了,根據IDE的提示需要在gradle.properties的末尾新增一行程式碼,很明顯這個是幹嘛用的。
android.useDeprecatedNdk=true
11.接下來嘗試從main Activity中呼叫一下程式碼
package com.dragon.opengles01;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.dragon.opengles01.ndk.NDKTest;
public class Main extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.ndk_test);
String str = NDKTest.hello();
textView.setText(str);
}
}
12.然後跑一下,又紅了,載入類出錯,需要在App模組下的gradle檔案中新增
ndk {
moduleName "ndk_test" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定三種abi體系結構下的so庫,目前可有可無
}
新增的地方如下,別新增錯了,生成的.so名字要和之前生成的一致,如果你不知道你生成的.so檔案是什麼名,請看下面。
13.最後,跑一下,成功了嗎?毛啊,又紅了,老提示下面錯問題
原因:jni周意男下的.h和.cpp中宣告的標頭檔案和實現檔案不一致,解決辦法,修改其中之一,一般.h檔案是自動生成的,所以建議不修改,一般要修改的話,修改.cpp檔案中的內容,修改成如下
14.最後成功了,廢話不多說,上圖
15,到這裡,誰能體會本文內心的陰影面積,故做此文希望大家少走彎路,一次成功。
如果你還有問題沒解決,你可以加入我們一起交流,專注於AR的在移動端的實現