我用eclipse jni开发开发安卓jni程序时发现,只有将工作空间设为一个文件夹时程

传智播客旗下品牌:& & | &
改变中国IT教育,我们正在行动 &&&&全国咨询热线:400-618-4000
广州校区 
传智播客官方微信
黑马程序员官方微信
400-618-4000&&&& 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK。而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自动编译NDK了。那么我们现在开始吧:
一、关于NDK的一点解释:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
NDK全称:Native Development Kit。
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出&哪些文件需要编译&、&编译特性要求&等),就可以创建出so。
NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
二、NDK坏境搭建:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
& 注意事项:目前已经出了NDK-r9b了,由于作者写这篇日志的时候 当时下载的还是NDK-r8c,所以仍以NDK-r8c为例来讲解。
操作类似,从ndk-7后,谷歌已经改良了ndk的操作,不需用使用cygwin来交叉编译了,这大大的提高了我们的开发速度。
(1)下载安装NDK-r8c。
下载地址:
(2)打开Eclipse,新建一个Android工程(我的取名为TestNdk),在工程目录TestNdk下新建jni文件夹,该文件夹就用来保存NDK需要编译的文件代码等。
(3)开始新建并配置一个Builder
(a)Project-&Properties-&Builders-&New,新建一个Builder。
(b)在弹出的【Choose configuration type】对话框,选择【Program】,点击【OK】:
(c)在弹出的【Edit Configuration】对话框中,配置选项卡【Main】。
在&Name&中输入新builders的名称(这个名字可以任意取)。
在&Location&中输入nkd-build.cmd的路径(这个是下载完ndk8后解压后的路径,这个建议放在根目录下面,路径不能有空格和中文)。根据各自的ndk路径设置,也可以点击&Browser File System&&来选取这个路径。
在&Working Diretcoty&中输入TestNdk位置(也可以点击&Browse Workspace&来选取TestNdk目录)。如图1
(d)继续在这个【Edit Configuration】对话框中,配置选项卡【Refresh】。如图2
勾选&Refresh resources upon completion&,
勾选&The entire workspace&,
勾选&Recuresively include sub-folders&。
(e)继续在【Edit Configuration】对话框中,配置选项卡【Build options】。
勾选&After a &Clean&&,(勾选这个操作后,如果你想编译ndk的时候,只需要clean一下项目 就开始交叉编译)
勾选&During manual builds&,
勾选&During auto builds&,
勾选&Specify working set of relevant resources&。如图3
点击&Specify Resources&&勾选TestNdk工程中新建的&jni&目录,点击&finish&。 点击&OK&,完成配置。 如图4
到此,恭喜你,编译环境以及成功搭建完毕!
那么搭建完了,当然要玩一玩了,好了,下面我们来跑一个demo测试一把,让你了解一下ndk的开发流程
三、NDK程序demo的开发(下面是重点,请仔细查看)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&& 1.在TestNdk工程中新建一个JniClient.class(为了调用C/C++代码),其内容如下:
package com.ndk.
public class JniClient {
static public native String AddStr(String strA, String strB);
static public native int AddInt(int a, int b);
2.生成 .h 的c++头文件
(1)用cmd命令定位到JniClient.class 所在目录,输入&javac JniClient.java&后回车,生成JniClinet.class文件(如果是用的Eclipse建的工程,在TestNdk\bin\classes\com\ndk\test目录下就已经有JniClinet.class文件了)。
(2)将JniClinet.class拷贝到TestNdk\bin\classes\com\ndk\test目录,将cmd命令定位到TestNdk\bin\classes目录,输入&javah com.ndk.test.JniClient&后回车,在TestNdk\bin\classes目录下就生成了C++头文件com_ndk_test_JniClient.h
com_ndk_test_JniClient.h的文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include &jni.h&
/* Header for class com_ndk_test_JniClient */
#ifndef _Included_com_ndk_test_JniClient
#define _Included_com_ndk_test_JniClient
#ifdef __cplusplus
extern "C" {
com_ndk_test_JniClient
* Signature: (Ljava/lang/SLjava/lang/S)Ljava/lang/S
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr
(JNIEnv *, jclass, jstring, jstring);
com_ndk_test_JniClient
* Signature: (II)I
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
3.在jni目录下新建一个Android.mk文件,其内容如下(关于mk文件需要注意,很重要,还有c和c++文件的mk文件还不一样,此处是调用c语言的mk文件,至于其他的怎么调用,这个自己去百度吧,在此就不多说了)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TestNdk
LOCAL_SRC_FILES := com_ndk_test_JniClient.c
include $(BUILD_SHARED_LIBRARY)
4. 将刚刚手动生成的com_ndk_test_JniClient.h拷贝到TestNdk工程的jni目录下,
然后新建一个com_ndk_test_JniClient.c文件完成头文件中函数的实现,其内容如下(本来想写两个方法的,现在只讲解第一个方法,返回一个字符串&HelloWorld from JNI &,另一个方法是一个a+b的运算,方法写到这里,感兴趣的可以自己去研究):
com_ndk_test_JniClient.c
#include "com_ndk_test_JniClient.h"
#include &stdlib.h&
#include &stdio.h&
#ifdef __cplusplus
extern "C"
com_ndk_test_JniClient
* Signature: (Ljava/lang/SLjava/lang/S)Ljava/lang/S
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr
(JNIEnv *env, jclass arg, jstring instringA, jstring instringB)
jstring str = (*env)-&NewStringUTF(env, "HelloWorld from JNI !");
com_ndk_test_JniClient
* Signature: (II)I
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt
(JNIEnv *env, jclass arg, jint a, jint b)
return a +
#ifdef __cplusplus
此刻,当编辑com_ndk_test_JniClient.c并保存后,project下的&clean& 一下工程,就可以看到TestNkd工程下的obj/local/armeabi目录下将自动生成libTestNdk.so库。
5.在TestNdkActivity.java中完成对JniClient.java中函数的调用(首先静态加载动态链接so库):
package com.ndk.
import android.app.A
import android.os.B
import android.widget.TextV
public class TestNdkActivity extends Activity {
System.loadLibrary("TestNdk");
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//第一个方法传入的两个参数没有做操作,直接返回hello jni,不用管
String str = JniClient.AddStr("test", "test");
//第二个方法暂时不实现
int iSum = JniClient.AddInt(5, 2);
// String strSum = "5 + 7 = " + iS
TextView tv1 = new TextView(this);
tv1.setText(str);
setContentView(tv1);
6.运行TestNdk工程,在控制台中可以看到界面输出来自com_ndk_test_JniClient.c 文件中的&HelloWorld from JNI ! "了。
NDK实例到此完成。
后续更复杂的操作就需要深入的学习NDK/JNI了,
比如C/C++与Java的数据类型转换,以及Android.mk文件的编写格式等。
如果有什么问题,欢迎沟通交流!非常感谢您对andye的关注!关于.h文件怎么生成,可以看我另一篇日志,虽然是用cygwin写的,有点旧,但是里面有关于怎么生成.h的截图,供参考,地址为:
近期有朋友需求,忘记上传一份demo了,那么我重新整理了一份demo,各位朋友可以下载学习:
百度网盘下载地址:/s/1gdIeUvL
demo图片如下:
阅读(...) 评论()安卓开发使用Eclipse时,想要修改Compile With 中的API ,但是里面只有一个选项_百度知道用eclipse进行安卓开发的问题,在布局文件中,设置了一个按钮后,没有报错,但是运行的时候没有显示_百度知道Eclipse下的Android JNI 开发
1 创建Android工程
首先建立一个名为AndroidJniTest的Android工程,包名默认为com.example.androidjnitest,src目录下自动创建MainActivity.java。
2 设计JNI接口
创建新的文件包com.example.jni,并在改包下新建一个TestJNI.java的类。
打开TestJNI.java,我们将在这个文件里创建一个JNI接口类,该Java类提供一个加法运算的接口:
public class TestJNI {
public native boolean init();
public native int add(int x , int y);
public native void destory();
注意,这里的函数声明要加上native关键字。
将TestJNI.java文件复制到工程的bin目录下,在终端中进入该工程的bin目录,输入javac TestJNI.java,这时会生成一个TestJNI.class文件。
在bin文件夹下,如果没有则创建目录:/com/example/jni,并把TestJNI.class复制到/bin/com/example/jni目录下。然后在终端里进入工程的bin目录,输入javah -jni com.example.jni.TestJNI,此时会生成一个com_example_jni_TestJNI.h文件。
com_example_jni_TestJNI.h文件就是对应于上面定义的Java接口的C/C++头文件。打开这个文件,可以看到系统已经为我们自动完成了接口函数的声明:
这三个函数分别对应于JNI的三个接口函数,命名方式只是在前面加上了Java包名。
4 用C/C++实现JNI
有了JNI的C/C++头文件,就可以在C层实现JNI接口了。首先在工程目录下创建一个jni目录,这个目录就是专门用来放C/C++代码的。把com_example_jni_TestJNI.h文件复制到jni目录下,并在这里创建一个com_example_jni_TestJNI.cpp文件。
由于我想用C++来实现JNI,所以上面两个文件我只是用来作为动态链接库的接口,具体的实现我希望放在一个类里面来完成,因此我再添加两个文件:Add.h和Add.cpp。
下面我们就来实现CAdd类和JNI接口。首先实现CAdd类:
#ifndef JNI_TEST_ADD
#define JNI_TEST_ADD
class CAdd{
int add(int x, int y);
#include "Add.h"
CAdd::CAdd(){
CAdd::~CAdd(){
int CAdd::add(int x, int y){
return x+y;
然后我们来写com_example_jni_TestJNI.cpp,实现JNI:
#include "Add.h"
CAdd *pCAdd = NULL;
JNIEXPORT jboolean JNICALL Java_com_example_jni_TestJNI_init
(JNIEnv *env, jobject obj){
if(pCAdd==NULL){
pCAdd = new CA
return pCAdd!=NULL;
JNIEXPORT jint JNICALL Java_com_example_jni_TestJNI_add
(JNIEnv *env, jobject obj, jint x, jint y){
jint res = -1;
if(pCAdd!=NULL){
res = pCAdd->add(x,y);
JNIEXPORT void JNICALL Java_com_example_jni_TestJNI_destory
(JNIEnv * env, jobject obj){
if(pCAdd!=NULL){
delete pCA
pCAdd=NULL;
到此我们的C/C++部分就全部实现了。
5 创建mk文件
JNI实现了之后就要把C/C++代码编译成动态链接库.so文件,这样Java程序才能调用JNI的接口。要编译so文件,需要写Android.mk和Application.mk两个文件。我们先来写Android.mk。
先在工程目录的jni下创建一个Android.mk文件:
然后打开文件在里面输入如下内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE
:= TestJNI
LOCAL_SRC_FILES := com_example_jni_TestJNI.cpp
LOCAL_SRC_FILES += Add.cpp
include $(BUILD_SHARED_LIBRARY)
其中LOCAL_PATH是C/C++代码所在目录,也就是我们的jni目录。
LOCAL_MODULE是要编译的库的名称。编译器会自动在前面加上lib,在后面加上.so。
LOCAL_SRC_FILES是要编译的C/C++文件。
现在我们在工程的根目录下创建一个Application.mk文件,并输入如下内容:
APP_PROJECT_PATH := ${call my-dir}
APP_MODULES := TestJNI
6 编译动态链接库
写完了mk文件就可以开始编译C/C++代码了。
默认在Windows7下配置好了NDK开发环境,打开cygwin,进入到工程目录。
在终端里进入工程的根目录,输入命令“$NDK/ndk-build”命令即可编译
编译成功后会在工程目录的libs/armeabi目录下生成一个libTestJNI.so文件。
7 在Java中调用JNI
现在我们的Android应用可以调用JNI计算加法的代码,如下:
System.load("TestJNI");
TextView tvX =
TextView tvY =
TextView tvSum =
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvX = (TextView)findViewById(R.id.et_x);
tvY = (TextView)findViewById(R.id.et_y);
tvSum = (TextView)findViewById(R.id.et_sum);
btnAdd = (Button)findViewById(R.id.btn_add);
btnAdd.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
int x = Integer.valueOf( tvX.getText().toString());
int y = Integer.valueOf( tvY.getText().toString());
int sum = 0;
TestJNI jni = new TestJNI();
boolean flag = jni.init();
sum = jni.add(x, y);
btnAdd.setText(String.valueOf(sum));
程序运行结果:
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

我要回帖

更多关于 eclipse jni 文件夹 的文章

 

随机推荐