Android NDK:②第一个NDK程序(创建步骤&一些问题)

Android NDK:②第一个NDK程序(创建步骤&一些问题)

本节内容是:演示搭建第一个NDK程序

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)即可.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。