Android環境搭建(含NDK的配置與使用,如果需要自己編譯so庫則可參考該內容,如果只使用其他人編譯好的so則可略過NDK配置)


一.Android開發之Eclipse環境搭建

  補充:Eclipse版本:到Eclipse官方網站下載Ecplise For Java EE;如果想在eclipse里開發C /C++,可以安裝CDT,安裝方法同ADT
    安裝JDK1.6,配置環境變量JAVA_HOME 、CLASSPATH、 path-->解壓Eclipse-->安裝ADT 插件-->解壓完整版(指解壓后即可使用無需安裝)SDK並配置android環境變量-->Eclipse中配置SDK路徑
部分步驟拆分:

    1>JDK安裝后環境變量配置: 安裝JDK到H:\Program Files (x86)\Java\jdk1.6.0_32

右擊“我的電腦”-->點擊“屬性”-->選擇“高級”選項卡-->點擊“環境變量” -->在“系統變量”中設置3項屬性,JAVA_HOME,PATH,CLASSPATH(大小寫無所謂),若已存在則點擊“編輯”,不存在則點擊“新建”

         JAVA_HOME變量值設為: H:\Program Files (x86)\Java\jdk1.6.0_32

         PATH變量值設為:在最前面加入%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

         CLASSPATH變量值在最前面加.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;

      檢測JDK配置是否成功:

開始 -> 運行 ,輸入cmd,進入dos系統界面然后打java -version,如果安裝成功系統會顯示java的版本信息
 

   2>配置android環境變量

    安裝android的SDK后為了方便也可以設置環境變量比如路徑為:

         H:\android-sdk-windows

    環境變量配置:

         ANDROID_HOME變量值設為:H:\android-sdk-windows

         PATH設置:在最前面加入: %ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools\;

           3>ADT安裝步驟

         1)打開Eclipse,Help -->Install New Software... -->選擇Work with:后的Add...。

         2)在Local選項中輸入ADT,在Archive中瀏覽到你的ADT壓縮包,點擊OK,然后在下 面勾選Name中的選項即可。
     安裝是否成功測試:

         1)安裝完ADT插件后,關閉Eclipse,然后重啟。

         2)打開File ->New,看有無出現Android Project選項,沒出現先別着急,再點擊Other...選項 ,看看General選項下是否有Android選項,有,則安裝成功,無,則安裝失敗
     4>Eclipse中配置SDK路徑
        Window-->preference-->左側Android選項卡-->右側SDK Location中瀏覽到你的SDK解壓路徑-->apply-->ok
 
 
項目中直接調用他人so庫的可以跳過二、三、四
 
二.(window環境下)Eclipse中編譯so庫環境的搭建(Eclipse+NDK+Cygwin)
  1> 安裝 Cygwin
    install from local dircal directory-->下一步-->Root Directory中輸入c:\cygwin-->下一步-->瀏覽到安裝包-->下一步-->devel改成install-->下一步,安裝成功后會在C:\cygwin\home\電腦名稱目錄下生成.bash_profile文件,打開這個文件

加入ANDROID_NDK_HOME=/cygdrive/d/android_soft/android-ndk-r4b-windows/android-ndk-r4b

export ANDROID_NDK_HOME保存(linux下配置環境變量,只有使用export關鍵字定義后才能使用,類似於windows下配置環境變量)

 

 

 

 

  2>eclipse中進行如下配置(使用Cygwin)對C/C++進行編譯得到*.so(C或C++編譯出來動態鏈接庫,該庫的名字會在Android.mk中通過LOCAL_MODULE進行配置)文件

備注:將ndk目錄下的samples中的hello-jni文件夾拷貝到自己的工作空間中,我的目錄為d:\Users\wanghu\workspace

  1)在新建的 android工程名上點右鍵->properties->Builders 右邊選擇New->Program

       location和Working Directory地址為Cygwin地址 分別為 C:\cygwin\bin\bash.exe  C:\cygwin\bin

       Arguments:

--login -c "cd /cygdrive/d/Users/wanghu/workspace/hello-jni && $ANDROID_NDK_HOME/ndk-build"

d/Users/wanghu/workspace/hello-jni這部分根據你的工程地址和名稱改變,這里$ANDROID_NDK_HOME與/ndk-build之間沒空格,之前寫錯了

  2)Refresh選項卡:勾選第一項Refresh resources upon completion.如下圖

 

 

  3)操作如下圖,然后點擊OK

Specify Resources選擇c/c++源碼路徑  下圖:

三.(window環境下)Cygwin中編譯so庫環境的搭建(NDK+Cygwin)

1>安裝Cygwin 見<二.(window環境下)Eclipse中編譯so庫環境的搭建(Eclipse+NDK+Cygwin)>中步驟1

2>開始編譯

  1)將ndk目錄下的samples中的hello-jni文件夾拷貝到自己的工作空間中,我的目錄為d:\Users\wanghu\workspack

  2)運行Cygwin,cd命令進入到hello-jni的目錄

cd d:/Users/wanghu/workspace/hello-jni

3)輸入如下命令然后回車進行編譯,

$ANDROID_NDK_HOME/ndk-build

 

四.(window環境下)Android Studio中編譯so庫環境的搭建(NDK+Android Studio)

1).新建項目 JniDemo

2).切到project視圖

3).創建jni目錄

   切到project,在項目的app工程右擊->New->Folder->Jni Folder->保持默認選擇finish

 

4).使項目支持NDK

     修改根目錄下gradle.properties文件,添加如下代碼

      

#支持NDK編譯C/C++源碼
 android.useDeprecatedNdk=true

 

5).設置NDK路徑

    修改根目錄下local.properties文件,添加自己的NDK路徑我的存放在D:\android-ndk-r12b-windows-x86_64\android-ndk-r12b

ndk.dir=D\:\\android-ndk-r12b-windows-x86_64\\android-ndk-r12b

 

6).build.gradle文件中在尾部追加如下代碼並根據喜好修改"useCustomMk"的值即可

 

 
          
// #################    需要編譯C/C++源碼的加入該代碼(只需根據喜好修改useCustomMk的值) start ################
android{
// 不要修改此變量的值,表示使用NDK編譯功能,注意:gradle.properties中的android.useDeprecatedNdk的值必須設置成true
def openNdk = true;

// 是否用自己的mk文件(Android.mk和Application.mk),為true時必須(在src/main/jni目錄)寫自己的mk文件。根據自己喜好修改此變量
def useCustomMk = false

if(openNdk){
// 如果用自己寫的mk文件編譯so生成目錄 "app/src/libs"
if(useCustomMk){
// 得到ndk路徑見 local.properties中定義的ndk.src
def ndkDir = project.plugins.findPlugin('com.android.application').sdkHandler.getNdkFolder()

sourceSets.main{
//set .so files directory to libs
jniLibs.srcDir 'src/main/libs'
//disable automatic ndk-build call禁用自動執行ndk-build
jni.srcDirs = []
}

// 定義編譯的task
task buildNative(type: Exec) {
//路徑為自己NDK所在位置,見 local.properties中定義的ndk.src
commandLine "$ndkDir/ndk-build.cmd", '-C', file('src/main').absolutePath
}

tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
}else{// 如果用自己寫的mk文件編譯so生成目錄 "app/build/intermediaters/ndk/debug"
defaultConfig {
// 如果不用自己寫的mk文件編譯
if(openNdk && !useCustomMk){
// ndk不用自定義mk文件自動編譯(系統會自動在app/build/intermediaters/ndk/debug目錄生成Android.mk文件,並自動關聯app/src/main/jni下的c/c++源碼,編譯完成后的so和臨時文件也會在這個目錄下生成)的配置
ndk{
stl "gnustl_static" // 設置支持標准的C++庫比如#include <string>中的一些方法
moduleName "jniTest" //修改此處:生成的so名字,同Android.mk中的LOCAL_MODULE
abiFilters "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "mips64", "x86_64" //輸出指定三種abi體系結構下的so庫(armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64)。同Application.mk中的APP_ABI
}
}
}
}
}
}
// ################# 需要編譯C/C++源碼的加入該代碼 end ################
 
         

 

7).java中寫自己的native方法,app項目中新建包名jnimanager,並在里面聲明一個專門用來存放native方法的單例類JniManager.java,源碼如下

 

package jnimanager;

/**
 * Created by bravestarr on 2016/9/28.
 *
 * SingleInstance class for JNI native method
 */
public class JniManager {
    private static JniManager mInstance = null;

    static{
        System.loadLibrary("jniTest");
    }

    private JniManager(){
    }

    /**
     * @return
     */
    public static JniManager getInstance(){
        if(null == mInstance){
            synchronized (JniManager.class){
                if(null == mInstance){
                    mInstance = new JniManager();
                }
            }
        }
        return mInstance;
    }

    /**###############################################################
     *      can add your Native methods below
     *################################################################*/

    /**
     * getContent
     * @param pName
     */
    public native String getContent(String pName);
}

 

8).Android Studio生成*.h頭文件

     進入Terminal,進入到java源碼路徑,通過 javah -d ../jni -jni 類名 命令生成頭文件(注意:1.類名不加class而且要用完整包名;2.前提是已配好java環境變量,否則javah命令不可用)見如下Terminal窗口信息

D:\workspaces\git_workspace\JniDemo>
        
        D:\workspaces\git_workspace\JniDemo>cd app/src/main/java

        D:\workspaces\git_workspace\JniDemo\app\src\main\java>javah -d ../jni -jni jnimanager.JniManager

運行上面命令后,會在jni目錄中自動生成一個頭文件jnimanager_JniManager.h,格式如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnimanager_JniManager */

#ifndef _Included_jnimanager_JniManager
#define _Included_jnimanager_JniManager
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jnimanager_JniManager
 * Method:    getContent
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_jnimanager_JniManager_getContent
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

 

9).jni目錄新建C/C++ class 例如此處創建C++的class  jnimanager_JniManager.cpp

右擊jni文件夾->New->C/C++ Source File->Type選擇.cpp,錄入名字jnimanager_JniManager->OK->將頭文件jnimanager_JniManager.h中需要實現的方法拷貝到jnimanager_JniManager.cpp中,並加上如下代碼

#include "jnimanager_JniManager.h"

 

注意:C++類與C的源文件有區別,native方法的實現需要放在extern "C" { }中,例如:

jnimanager_JniManager.cpp的完整源碼如下:

//
// Created by bravestarr on 2016/9/28.
//
#include "jnimanager_JniManager.h"
#include <string>

extern "C" {
/*
 * Class:     jnimanager_JniManager
 * Method:    getContent
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_jnimanager_JniManager_getContent
  (JNIEnv * env, jobject, jstring jName){
      const char *jnameStr1 = env->GetStringUTFChars(jName, NULL);
      // 定義拼接后的結果內容
      char jnameStr[100] = "";
      // 標准拼接的方法 須#include <string>
      strcat(jnameStr,jnameStr1);
      strcat(jnameStr,",你好");
      return env->NewStringUTF(jnameStr);
  }

}

 

10).jni目錄新建Android.mk和Application.mk文件,格式如下:

Android.mk內容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#關聯的本地C++源碼
LOCAL_SRC_FILES  := jnimanager_JniManager.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS     += -llog -ldl

#編譯后的so庫的名字
LOCAL_MODULE     := jniTest

include $(BUILD_SHARED_LIBRARY)

 

Application.mk內容如下:

#設置使用標准的C++庫
APP_STL := gnustl_static
#C++代碼的編譯選項
APP_CPPFLAGS := -frtti -fexceptions
#設置要生成的架構的.so文件(armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64),想生成多個so,可以修改APP_ABI后再進行打包
APP_ABI := armeabi-v7a #這句是設置最低安卓平台,可以不弄 APP_PLATFORM := android-18

 

11),在MainActivity中調用調用native方法,MainActivity完整源碼

package enterprisedigital.hiko.com.jnidemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import jnimanager.JniManager;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String _content = JniManager.getInstance().getContent("張三");
        Toast.makeText(this,_content,Toast.LENGTH_LONG).show();
    }

}

 

11).Build->Make Project編譯出so,並啟動程序

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM