zoukankan      html  css  js  c++  java
  • Android的NDK开发步骤

    一个超级快配置NDK的办法:(NDK DEMO)

    第一步:

    到Android官网下载Android的开发工具ADT(Android Development Tool的缩写),该工具集成了最新的ADT和NDK插件以及Eclipse,还有一个最新版本SDK。解压之后就可以用了。

    ADT插件:管理Android SDK和相关的开发工具的

    NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件。也可以在线更新ADT、NDK插件

    第二步:

    到Android官网下载最新的NDK,注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。比起下载Cygwin要方便多啦!下载链接见:http://developer.android.com/tools/sdk/ndk/index.html

    第三步:

    打开Eclipse,点Window->Preferences->Android->NDK,设置NDK路径,例如E:/android-ndk-r9c

    第四步:

    新建一个Android工程,在工程上右键点击Android Tools->Add Native Support...,然后给我们的.so文件取个名字,例如:my-ndk

    这时候工程就会多一个jni的文件夹,jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的源文件。

     

    第五步:

    接下来仿着NDK的demo,Hello-JNI工程写一下。使用Alt + '/'可以代码提示

    JNI接口的命名规范是:Java_ + 调用该方法的包名(包名的点用_代替) + _ + 调用该接口的类名 + _ + 方法名,对于实例方法,有两个参数是必要的,一个JNI的环境指针JNIEnv *,另一个是调用该方法的Java实例jobject

    my-ndk.cpp:

     #include JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv *env,jobject thiz) {  

      return env->NewStringUTF("Hello jni");}


    TestActivity.java:

    public class TestActivity extends Activity { static { System.loadLibrary("my-ndk"); } // 声明JNI层的原生方法,使用native关键字 public native String stringFromJNI(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tvText = new TextView(this); tvText.setText(stringFromJNI()); setContentView(tvText); }}


    使用ndk库必须在static代码块里面用System.loadLaibrary加载.so库
     

    第六步:

    完成了,然后运行。运行之前先编译NDK,然后在编译JAVA代码。编译也许会遇到Unable to launch cygpath. Is Cygwin on the path?错误,解决办法如下:

    1.工程右键,点Properties->C/C++ Build的Building Settings中去掉Use default build command,然后输入${NDKROOT}/ndk-build.cmd

    2.在C/C++ Build中点击Environment,点Add...添加环境变量NDKROOT,值为NDK的根目录

    3.再编译,问题就解决啦!

    运行时崩溃,遇到java.lang.UnsatisfiedLinkError: stringFromJNI错误,解决办法:在C++文件中函数定义前添加extern "C"修饰

     

    extern "C" {JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv *env,		jobject thiz);}JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv *env,		jobject thiz) {	return env->NewStringUTF("Hello jni");}

    原因是:使用extern "C"修饰,编译器会按C语言的方式编译和连接。在C语言中,函数编译之后函数名与C++函数编译之后不同,例如foo(int x, int y),C可能会编译成_foo的名字,而C++因为支持重载,所以会编译成像_foo_int_int这种带参数的函数名。如果是按照C语言的编译方式,调用foo函数是找不到_foo的函数名就会报出函数名找不到的错误。所以要添加extern "C"修饰。

     参考文章:

    http://blog.csdn.net/pi9nc/article/details/28855737
    http://www.2cto.com/kf/201403/288157.html
    http://www.th7.cn/Program/Android/201404/189197.shtml

  • 相关阅读:
    新添61工程文件后无法编译问题
    beaglebone_black_学习笔记——(4)闪烁LED之shell命令
    PADS技巧——铺铜
    自定义map对象,用于再不支持es6的map的时候
    vue.js基础学习(2)
    vue.js基础学习(1)
    ie浏览器float兼容性
    webAPI路由的使用
    webAPI中使用log4net进行日志记录
    webAPI中使用FormsAuthenticationTicket作为登录权限票据
  • 原文地址:https://www.cnblogs.com/ZSS-Android/p/4530025.html
Copyright © 2011-2022 走看看