Android NDK 开发

说到 NDK 开发,其实是为了有些时候为了项目需求需要调用底层的一些 C/C++ 的一些东西;另外就是为了效率更加高些。谷歌主力推动 Android Studio 这个是个不错的工具,至少现在来看在 Eclipse 上能做到的 这边都有,这边有的Eclipse上不一定有。但是为了复习,两个IDE都记录一下。

准备工作

去官网下载NDK,这个需要翻墙,下面发放福利了。

  1. http://yunpan.cn/cdFTKe3Ty4D9e 访问密码 6776(Android-ndk-r10e0)
  2. http://yunpan.cn/cdFTQAmSAI9sY 访问密码 f594(我下载的翻墙工具,勉强过得去)

下载好了ndk,双击解压到当前目录,貌似时间有点忽悠人,耐心等待一下。接下来我们可以开始NDK开发了。之前我们可以去ndk目录下找samples,找官网给的例子。学习ing中……先从Eclipse开始吧。

一、Eclipse DNK开发

1、建立一个项目HelloNDK

在Activity 中写一个native方法

public class MainActivity extends Activity {

    static{
        System.loadLibrary("hello");
    }
    /**
     * native 
     * @return
     */
    public static native String getStringFromC();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView text = (TextView) findViewById(R.id.textView);
        text.setText(getStringFromC());
    }
}

写好了native方法后。来到java目录,执行javah命令,生成c/c++所需要的头文件xxx.h
这里写图片描述

-classpath 是项目bin目录下class文件
-d 输出目录(jni,是我刚才在工程目录下建好的jni文件夹)

**xxx/xxx/xxx.h文件**

extern "C" {
/*
 * Class:     com_example_jnindk_MainActivity
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_jnindk_MainActivity_getStringFromC
  (JNIEnv *, jclass);
#ifdef __cplusplus
}

之后去官网的例子jni文件夹把Android.mk,application.mk复制到现在的工程jni文件夹。

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello
LOCAL_SRC_FILES := hello.c

include $(BUILD_SHARED_LIBRARY)

注意LOCAL_MODULE本地的moduleName。LOCAL_SRC_FILES本地写的c文件。

2、我们在jni文件夹中写一个hello.c文件

#include<stdio.h>
#include<stdlib.h>
#include "com_example_jnindk_MainActivity.h"

JNIEXPORT jstring JNICALL Java_com_example_jnindk_MainActivity_getStringFromC
  (JNIEnv * env, jclass jclass){

     return (*env)->NewStringUTF(env, "Hello from the world !");
};

返回一个字符串。仔细看类名,第一个是Java,接下是包名+类名+方法名。这里包名跟我cmd中写的类名不一样,失误,上面是我随便写的,注意一下就可以。

3、生成so文件
这里写图片描述

成功后会在工程目录生成一个obj文件夹,这里可以找到so文件。
这里写图片描述
做过百度地图的朋友们有没有看到so,感到很亲切。接下我们就去Maintivity中调用了。

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

测试通过。

二、下面把NDK开发切换到Android studio下。

前面的步骤差不多,只是不需要我们敲命令去生成so文件,我们在build.gradle中去配置就可以了。
这里写图片描述

注意ndk的位置,defaultConfig下面。
这里写图片描述

ndk的位置

刚在Eclipse中我们手动命令生成so文件,as只需要配置重新build的时候这个so文件生成都哪儿去了呢。请看。
这里写图片描述
看lib,so文件移植到这么多的APP_ABI里面。这是如何做到的,我们发现application.mk中的配置。和build.gradle中ndk的配置。

APP_ABI := APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64

APP_PLATFORM := android-

三:错误总结
1、`Error:Execution failed for task ‘:app:compileDebugNdk’.

com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘D:\Users\htj-123\AppData\Local\Android\android-ndk-r10b\ndk-build.cmd” finished with non-zero exit value 2`

这个是我工程目录有空格导致的。

2、Process: com.eddie.ndk, PID: 23210
java.lang.UnsatisfiedLinkError: Native method not found: com.eddie.ndk.MainActivity.getStringFromC:()Ljava/lang/String;

1) Android.mk里面:
最后生成的时候
LOCAL_MODULE := testcmmb_jni 千万不能写成 libtestcmmb_jni!!!!虽然编译出来的文件名称貌似相同
2) C++ 的代码里面:
extern “C”{
。。。
}
这是因为生成的二进制文件中,C和C++的符号表不相同造成的。Jni是按照C的生成规则去找函数的, 所以要加上extern C使编译器把函数按照C的规则编译 这样才能被JAVA调用

项目源码:Android NDK demo欢迎下载。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值