Android NDK:②第一个NDK程序(创建步骤&一些问题)
本节内容是:演示搭建第一个NDK程序
- Android NDK第一个NDK程序创建步骤一些问题
- 创建一个Android Project
- Java代码中声明native方法
- 创建Jni文件夹编写ccpp代码
- 为项目添加NDK支持
- 新建配置一个Builder
- 调用了native方法的地方加载库
- 好了把程序跑起来
- 总结
- 遇到的问题
1.创建一个Android Project
直接创建一个新的Android Application Project即可~
2.Java代码中声明native方法:
package com.jay.example.firstndk;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button btnShow;
// 声明native方法
public native String javaFromJNI();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShow = (Button) findViewById(R.id.btnShow);
btnShow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, javaFromJNI(),
Toast.LENGTH_SHORT).show();
}
});
}
}
3.创建Jni文件夹,编写c/cpp代码
这里要注意的地方有两个:
①返回值类型
jni.h文件中中事先定义的数据类型,我们可以在ndk/platforms/android-xx/arch-arm/user/include目录下找到,~xx代表版本号
打开jni.h我们会看到很多数据类型,我们这里的是string:
②方法名:按照下述规则:
返回值类型 Java_包名_类名_native方法名(JNIEnv* env, jobject obj)
而里头的参数是固定的,在jni.h文件我们也可以查到,他是一个叫做JNINativeInterface的结构体,结构体中定义了很多数据类型,我们找到那个返回字符串的:
好的,那么接下来我们把我们的c代码写完,我们在jni目录下创建一个叫first.c的文件:
#include<stdio.h>
#include<jni.h>
jstring Java_com_jay_example_firstndk_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) {
return (*env)->NewStringUTF(env, "First Blood~");
}
4.为项目添加NDK支持
工程右键->Android Tools ->Add Native Support输入so库名称:
自己给so库命名:
这个时候会看到,jni目录下除了我们自己编写的c文件外,还多了两个东东,xx.cpp和Android.mk文件,那个cpp可以直接删掉,接着打开Android.mk件,修改下东西:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := FirstNDK
LOCAL_SRC_FILES := first.c
include $(BUILD_SHARED_LIBRARY)
ps:其实这步可以直接在3就进行,会直接生成一个.cpp与Android.mk的文件的~
5.新建&配置一个Builder
右键Project->Properties->Builders->New,新建一个Builder,在弹出的对话框上面点击Program,OK!如图所示
双击打开,进行配置:
点击确定,OK,好了,接下来就可以自定编译代码了~比如我们修改代码后保存,他都会重新编译下.so
6.调用了native方法的地方加载库:
7.好了,把程序跑起来~
8.总结:
好了,第一个NDK程序就这样完成了,中途磕磕碰碰遇到很多问题,总算是顺利地跑起来了,下面归纳下大概步骤:
- 创建一个普通NDK工程
- 声明native方法
- 创建Jni文件夹,可以自己写个.c或者.cpp文件,或者直接第四步直接生成一个.cpp与Android.mk文件
- 为项目添加NDK支持
- 新建&配置一个Builder
- 调用了native方法的地方加载库(System.loadLibrary(xxx))
- 运行程序~~
好了,大概过程就如上面所述~可能还有其他快捷的创建方法吧,后续遇到的话在给大家介绍哈~最后附上弄这个程序时遇到的一些问题以及解决方法!
9.遇到的问题
1.运行后程序直接死掉- -,后来查log发现是c那里方法名写错了,直接报方法找不到!
解决方法:严格按照下述规定写
返回值类型 Java_包名_类名_native方法名(JNIEnv* env, jobject obj)
2.出现这样的提示:
Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 14 in ./AndroidManifest.xml
解决方法:
android-ndk-r8e/build/core/add-application.mk第128行把__ndk_warning改为__ndk_info;然后重新build一次项目即可消除错误。
或者,直接写成这样…我们公司是这样做的…感觉这样虽然不报错,但是不好…
3.用c来写的出现:Method ‘NewStringUTF’ could not be resolved
就是找不到方法,真奇葩…
解决方法:
比如我的路径是:
E:\NDK\android-ndk-r10d\platforms\android-17\arch-arm\usr\include
4.如果你用的是.cpp的话,出现3的问题
解决方法:为供Java调用的c++函数前加入extern “C” 修饰
另外输出字符串的语句也是不一样的:
(*env)->Method(env, XXX)改成env->Method(XXX)即可.