一.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的版本信息
安装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
加入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,并启动程序