zoukankan      html  css  js  c++  java
  • 新版本NDK环境结构(避Cygwin,超快)


    曾经做Android的项目要用到NDK就必需要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量...


    麻烦到不想说了,Shamoo在网上查了一下资料,发现了一个超级快配置NDK的办法。

    Step1:到Android官网下载Android的开发工具ADT(Android Development Tool的缩写),该工具集成了最新的ADT和NDK插件以及Eclipse,另一个最新版本号SDK。解压之后就能够用了,很爽!

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

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

    也能够在线更新ADT、NDK插件。只是速度超级慢...所以果断在网上下载集成开发工具ADT。下载链接见:http://developer.android.com/sdk/index.html


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

    下载完毕之后。解压搞定!


    Step3:打开Eclipse,点Window->Preferences->Android->NDK,设置NDK路径。比如Shamoo的是E:android-ndk-r9c

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

    这时候project就会多一个jni的目录。jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDKproject的Makefile。my-ndk.cpp就是NDK的源文件。


    Step5:接下来仿着NDK的demo,Hello-JNIproject写一下。使用Alt + '/'能够代码提示!非常爽!有木有?之前用CDT时候死活都按不出代码提示。郁闷...


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

    my-ndk.cpp:

    ?
    1
    2
    3
    4
    5
    6
    #include <jni.h>
     
    JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI(JNIEnv *env,
            jobject thiz) {
        returnenv->NewStringUTF("Hello jni");
    }</jni.h>

    TestActivity.java:

    ?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    publicclassTestActivity extendsActivity {
     
        static{
            System.loadLibrary("my-ndk");
        }
         
        // 声明JNI层的原生方法,使用nativekeyword
        publicnativeString stringFromJNI();
         
        @Override
        protectedvoidonCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            TextView tvText = newTextView(this);
            tvText.setText(stringFromJNI());
            setContentView(tvText);
        }
     
    }

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


    Step6:完毕了,然后执行。

    执行之前先编译NDK,然后在编译JAVA代码。编译或许会遇到Unable to launch cygpath. Is Cygwin on the path?错误,解决的方法例如以下:

    1.project右键。点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"修饰

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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) {
        returnenv->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/houshunwei/article/details/17217695

    Type 'JNIEnv' could not be resolved 等信息解决的方法        http://www.cnblogs.com/hlppsite/p/3349377.html


  • 相关阅读:
    Sublime Text 试玩日记
    Makefile 学习
    小书匠使用手册
    较完整的解决Linux zip 压缩包中文我乱码问题
    彻底解决Android模拟器中文短信乱码问题
    博客变更
    关于如何学习一个框架的经验总结
    [JavaScript] this、call和apply详解
    类与类之间关系,用C#和JavaScript体现
    [Node.js] require背后的故事
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4819151.html
Copyright © 2011-2022 走看看