美文网首页移动流媒体
Eclipse环境下进行Android NDK开发

Eclipse环境下进行Android NDK开发

作者: Hifate | 来源:发表于2016-02-18 13:43 被阅读215次

准备工作:

  1. JDK安装
  2. Eclipse 安装(包括ADT插件)
  3. Andorid SDK 下载安装
  4. Android NDK 下载安装

注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版,已经不需要单独安装Cygwin

第一个Demo

  1. 新建一个Android工程,然后在工程上右键点击Android Tools->Add Native Support… ,然后给我们的.so文件取个名字,例如我的是:FirstNDK,这时候工程就会多一个jni的文件夹,jni下有Android.mk和FirstNDK.cpp文件。Android.mk是NDK工程的Makefile,FirstNDK.cpp就是NDK的源文件。
    (关于 Android.mk 的说明可以参考资料:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/13/2137577.html
    JNI接口的命名规范是:Java_ + 调用该方法的包名(包名的点用代替) + + 调用该接口的类名 + _ + 方法名,对于实例方法,有两个参数是必要的,一个JNI的环境指针JNIEnv *,另一个是调用该方法的Java实例jobject
    接下来编辑FirstNDK.cpp文件,写一个FirstNDK的demo,代码如下:
#include <jni.h>
extern "C"{
    jstring 
    Java_com_example_firstndk_MainActivity_getStringFromJNI(JNIEnv* env, jobject thiz)
    {
        //返回一个字符串给Java层
        return env->NewStringUTF("Hello from JNI.");
        // return (*env)->NewStringUTF(env, "Hello from JNI.")
    }
}
  1. 然后在MainActivity调用我们刚刚编写的FirstNDK,代码如下:
public class MainActivity extends Activity {
    Button btn;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button);
        tv = (TextView) findViewById(R.id.text);
        btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tv.setText(getStringFromJNI() );
            }
        });

    }
    public native String getStringFromJNI();

    static {
        System.loadLibrary("FirstNdk");
    }
}

完成了,然后运行。运行时会先编译NDK,然后在编译JAVA代码。

问题与解决

问题1:编译也许会遇到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.再编译,问题就解决啦!

问题2:运行时崩溃,遇到java.lang.UnsatisfiedLinkError

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

问题3:Method 'NewStringUTF' could not be resolved 问题

因不想使用extern "C"修饰, 所以将FirstNDK.cpp改为FirstNDK.c,
同时将c++写法 env->NewStringUTF("HelloWorld from JNI.") 改为 c写法 (*env)->NewStringUTF(env, "Hello from JNI.")
遇到Method 'NewStringUTF' could not be resolved 问题
解决方法:右键工程 property->C/C++ General->Code Analysis—>配置当前工程(或者workspace)->使 method cannot be resolved 不选中(即此项不进行报错 )

相关文章

网友评论

    本文标题:Eclipse环境下进行Android NDK开发

    本文链接:https://www.haomeiwen.com/subject/vyvmkttx.html