android NDk初步学习以及某些小问题的解决方法备忘 一

最近做android项目,终于用到了NDK。我本身太懒,碰不到的东西都不想去学习,等到问题出来了才有劲头去研究。虽然项目本身的JNI问题在网上七凑八凑的搞定了,但是感觉NDK的内容还是要从头系统的学习一下,所以这里在标题后面加了个一。这个“一”可能会不断的增加,也可能就会这么一直孤独下去了……

    现在开始记录一下初次学习的步骤吧。刚学习我也是去网上找了一篇博客,博客地址如下:(http://blog.csdn.net/redoffice/article/details/6654714)这篇博客里面的作者写的很清楚,也

特别适合我这种懒人的入门学习。但是完全照着他的去做并不能走完一个流程,大部分原因应

该是jdk,ndk的版本导致的。这里我们还是以他的为基础,用最新的ndk(我的是ndk8)吧整

个流程再走一遍,顺便记录下某些问题的解决方法。


   首先,建立android工程,工程中的MainActivity内容如下(这里面的代码还是上文提到那篇

博客的代码,暂时不纠结这个,主要还是把流程走通):

   

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        TextView  myTextView = new TextView(this);
        myTextView.setText( stringTestNdk() );
        setContentView(myTextView);
    }

    public native String  stringTestNdk();
    public native String  stringTestNdk2();

    static {
        System.loadLibrary("testNDK");
    }
<span style="font-family:Arial, Helvetica, sans-serif;font-size:24px;"><span style="font-size: 18px; white-space: normal;">
</span></span>

    其中 System.loadLibrary("testNDK");是加载testNDK库文件(全名为libtestNDK.so)。两

个native方法是我们要在C/C++中实现的的native方法。


然后,打开cmd,进入工程下面输入javah -classpath bin/classes -d ndk com.exm.helloword.MainActivity

(这里注意原博客里面没有加入bin后面的classes,但是那样执行可能因为jdk版本问题会出错)。这样就生成了

一个.h文件。这个头文件貌似没用到,但是还是生成,待会写c/C++文件的时候可以吧函数名拷过去。

头文件的内容如下:

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

#ifndef _Included_com_exm_helloword_MainActivity
#define _Included_com_exm_helloword_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_exm_helloword_MainActivity
 * Method:    stringTestNdk
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk
  (JNIEnv *, jobject);

/*
 * Class:     com_exm_helloword_MainActivity
 * Method:    stringTestNdk2
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk2
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

这里生成的头文件默认生成在工程目录下的ndk目录下,我在工程下面新建了一个jni目录,

把头文件拷贝到到jni目录中,看里面的两个方法,命名规则是 包名+类名+函数名,括号里的两个参数是默认的。

再然后,在jni目录下新建一个testNSK.cpp的C++文件,里面的内容我直接把上文提到博客里面

的c内容加入进去,代码如下:

#include <string.h>
#include <jni.h>

JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk
(JNIEnv *env, jobject obj){
	 return (*env)->NewStringUTF(env, "Hello Test Little T !");
}

 

编写完成该C++文件以后,在jni目录下新建一个mk文件,命名为Android.mk内容如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= testNDK
LOCAL_SRC_FILES := testNDK.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)

 编写完mk文件后 
 用ndk编译上述文件,以便生成so文件。编译过程如下(适合ndk8以上,不用安装配置cygwin): 

在cmd中进入到工程的jni目录下,输入ndk命令D:\android\ndk-bulid(我没有配置环境变量,切ndk在该

目录下所以输入的是整个路径名称加上ndk命令)

编译过程到这里就算是结束了。但是我碰到了两个问题:

(1)the mangling of ‘va_list’ has changed in GCC4.4

在mk文件中加入 LOCAL_CFLAGS = -Wno-psabi,修改后mk文件如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
<span style="color:#FF0000;">LOCAL_CFLAGS = -Wno-psabi</span>
LOCAL_MODULE:= testNDK
LOCAL_SRC_FILES := testNDK.cpp
include $(BUILD_SHARED_LIBRARY) 

(2) base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}'

问题是原博客的是c文件,我写的是c++文件,所以要把testNDK.cpp的内容改为:

#include <string.h>
#include <jni.h>
extern "C" {
JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk(JNIEnv *env, jobject obj){
	 <return env->NewStringUTF("Hello Test Little T !");
}
<span style="color:#FF0000;">}

 
 

修改完成再运行ndk命令,便可在工程下发现多了一个obj包,包里面有个local文件夹,

可以找到libtestNDK.so的包。然后运行工程,便可输出如下信息。"Hello Test Little T !"


好了,到这里算是吧流程走完了,但是里面的很多概念性的东西还不是很了解,

当然上文提到的博客里面有比较详细明了的说明,更细节的和深入的内容有

待继续去学习,希望那个“一”不会孤独下去。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值