zoukankan      html  css  js  c++  java
  • 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,并启动程序

     

  • 相关阅读:
    NOIP201208同余方程
    NOIP模拟赛 最佳组合
    NOIP模拟赛 拓展
    CF1253E Antenna Coverage(DP)
    LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)
    CF582E Boolean Function(DP,状态压缩,FMT)
    CF750G New Year and Binary Tree Paths(DP)
    Codeforces Round 596 题解
    AGC008E Next or Nextnext(组合计数,神奇思路)
    ARC082E ConvexScore(神奇思路)
  • 原文地址:https://www.cnblogs.com/bravestarrhu/p/2479415.html
Copyright © 2011-2022 走看看