一.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,并启动程序

 

 

posted on 2012-05-02 18:07  alex_wongh  阅读(7338)  评论(0编辑  收藏  举报