1.安装
1.下载NDK,注意下载的是r4版本
http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip
2.下载完成后解压到某一目录,我的是在
zhangweia@ubuntu:~/android/android-ndk-r4b$pwd
/home/zhangweia/android/android-ndk-r4b
zhangweia@ubuntu:~/android/android-ndk-r4b$echo $HOME
/home/zhangweia
3.配置NDK的环境变量
zhangweia@ubuntu:~/android/android-ndk-r4b$vi ~/.bashrc
在打开的文件末尾添加:
NDK=$HOME/android/android-ndk-r4b/
export NDK
执行下面的命令,保存环境便利,然后查看是否生效:
zhangweia@ubuntu:~/android/android-ndk-r4b$source ~/.bashrc
zhangweia@ubuntu:~/android/android-ndk-r4b$echo $NDK
/home/zhangweia/android/android-ndk-r4b/
4.编译例子。
进入NDK 的例子目录samples/hello-jni,然后在该目录下执行$NDK/ndk-build,编译成功后会在该目录多生成2个子目录libs,obj目录
然后打开eclipse ,添加存在的hello-jni工程 ,运行则
2.HelloNDk
bin/Hello.c
#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
*/
jstring Java_com_su_testjni_HelloJniActivity_stringFromJNI(JNIEnv* env,
jobject thiz) {
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
src/HelloJniActivity
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.su.testjni;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class HelloJniActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
* Create a TextView and set its content. the text is retrieved by
* calling a native function.
*/
TextView tv = new TextView(this);
tv.setText(stringFromJNI());
setContentView(tv);
}
/*
* A native method that is implemented by the 'hello-jni' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
/*
* This is another native method declaration that is *not* implemented by
* 'hello-jni'. This is simply to show that you can declare as many native
* methods in your Java code as you want, their implementation is searched
* in the currently loaded native libraries only the first time you call
* them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
public native String unimplementedStringFromJNI();
/*
* this is used to load the 'hello-jni' library on application startup. The
* library has already been unpacked into
* /data/data/com.example.hellojni/lib/libhello-jni.so at installation time
* by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
}
Android.mk
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni 这里是jni库将来的名字 源码同名就可以
LOCAL_SRC_FILES := hello-jni.c c源码
include $(BUILD_SHARED_LIBRARY)
编译的方法:cd到项目目录 然后ndk-build 就ok
3.java和c之间 数据交换
android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=Hello
LOCAL_SRC_FILES :=Hello.c
#liblog.so libGLESv2.so
LOCAL_LDLIBS += -llog //添加log
include $(BUILD_SHARED_LIBRARY)
制作头文件:
cd到bin目录然后javah com.test.testndkdata.DataProvider 含有nativte的方法
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_itcast_ndk3_DataProvider */
#ifndef _Included_cn_itcast_ndk3_DataProvider
#define _Included_cn_itcast_ndk3_DataProvider
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_add__II
(JNIEnv *, jobject, jint, jint);
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: sub
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_sub
(JNIEnv *, jclass, jint, jint);
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: add
* Signature: (CC)C
*/
JNIEXPORT jchar JNICALL Java_cn_itcast_ndk3_DataProvider_add__CC
(JNIEnv *, jobject, jchar, jchar);
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: sayHelloInC
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_itcast_ndk3_DataProvider_sayHelloInC
(JNIEnv *, jobject, jstring);
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: intMethod
* Signature: ([I)[I
*/
JNIEXPORT jintArray JNICALL Java_cn_itcast_ndk3_DataProvider_intMethod
(JNIEnv *, jobject, jintArray);
/*
* Class: cn_itcast_ndk3_DataProvider
* Method: byteMethod
* Signature: ([B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_cn_itcast_ndk3_DataProvider_byteMethod
(JNIEnv *, jobject, jbyteArray);
#ifdef __cplusplus
}
#endif
#endif
然后是c代码:
#include<stdio.h>
#include<jni.h>
#include "cn_itcast_ndk3_DataProvider.h";
#include <android/log.h>
#include<malloc.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
/**
* 返回值 char* 这个代表char数组的首地址
* Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串
*/
char* Jstring2CStr(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env,"java/lang/String"); //String
jstring strencode = (*env)->NewStringUTF(env,"GB2312"); // 得到一个java字符串 "GB2312"
jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env,barr); // byte数组的长度
jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
if(alen > 0)
{
rtn = (char*)malloc(alen+1); //"\0"
memcpy(rtn,ba,alen);
rtn[alen]=0;
}
(*env)->ReleaseByteArrayElements(env,barr,ba,0); //
return rtn;
}
JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_add
(JNIEnv * env, jobject obj , jint x, jint y){
LOGD("x=%d",x);
LOGD("y=%d",y);
return x+y;
}
JNIEXPORT jstring JNICALL Java_cn_itcast_ndk3_DataProvider_sayHelloInC
(JNIEnv * env, jobject obj, jstring jstr ){
//在c语言中 是没有java的String
char* cstr = Jstring2CStr(env, jstr);
LOGD("cstr=%s",cstr);
// c语言中的字符串 都是以'/0' 作为结尾
char arr[7]= {' ','h','e','l','l','o','\0'};
strcat(cstr,arr);
LOGD("new cstr=%s",cstr);
return (*env)->NewStringUTF(env,cstr);
}
/**env java 虚拟机 结构体c实现的指针 包含的有很多jni方法
*jobject obj 代表的是调用这个c代码的java对象 代表的是DataProider的对象
*/
JNIEXPORT jintArray JNICALL Java_cn_itcast_ndk3_DataProvider_intMethod
(JNIEnv * env , jobject obj , jintArray arr){
//1.知道数组的长度
//2.操作这个数组里面的每一个元素
int len = (*env)->GetArrayLength(env,arr);
LOGD("shuzu len =%d",len);
// jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
jint* intarr = (*env)->GetIntArrayElements(env,arr,1);
int i =0; //c99
for(;i<len;i++){
//*(intarr+i) += 10;
LOGD("intarr[%d]=%d", i, intarr[i]);
intarr[i]+= 10;
}
// void (*ReleaseIntArrayElements)(JNIEnv*, jintArray,
// jint*, jint);
//
// (*env)->ReleaseIntArrayElements(env,arr,intarr,0); // c语言释放掉 刚才申请的内存空间
return arr;
}
/**
* 代表的是调用c代码 的class类
* jclass DataProvider 类
*/
JNIEXPORT jint JNICALL Java_cn_itcast_ndk3_DataProvider_sub
(JNIEnv * env, jclass clazz, jint x, jint y){
LOGD("x=%d",x);
LOGD("y=%d",y);
return x-y;
}
然后是dataprovider代码
package com.test.testndkdata;
import android.R.integer;
public class DataProvider {
public native int add(int a, int b);
public native String sayHello(String s);
public native int[] ints(int[] nums);
}
所有代码
http://dl.vmall.com/c0hivk447p
分享到:
相关推荐
Android Studio 之 NDK篇中的代码实例
ndk jni的学习
了解ndk开发意义,熟悉ndk开发环境的搭建,和初步开发流程
jni-ndk学习+ue+source+图片jni-ndk学习+ue+source+图片
如何配置NDK环境,配置环境中可能出现问题,如何编写NDK代码等等
Android NDK 高手开发学习笔记,非常实用,保证物有所值哈~
android ndk开发笔记 你懂的 介绍了ndk开发的过程
Android NDK基础知识,看完一定会对NDK开发有很大的收获!
AndroidNDK学习笔记.pdf
NULL 博文链接:https://android-zhang.iteye.com/blog/1779326
AndroidStudio3.0的混合编译项目,详细的JNI与NDK基础,包括属性、方法、数组引用、以及异常处理,内存策略等...
ti dsp ndk c6455ti dsp ndk c6455 ti dsp ndk c6455 ti dsp ndk c6455 ti dsp ndk c6455
利用NDK实现简单加减乘除功能,为作业学习。 简单的native方法结合实现
这是2018年最新的ndk开发demo。Demo1.主要是ndk的编译包括ndk的环境cmaklists的配置等,Demo2 是使用编译出的.so的方式。 具体使用方式和教学请看我的Github:NDK开发三部曲 记得star哦 谢谢 ...
详细介绍 在Google android ndk平台下的 C开发
android-ndk(android-ndk-r26b-windows.zip)适用于Windows系统
博客名称 : 【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 ) 博客地址 : https://hanshuliang.blog.csdn.net/article/details/102933704
mac--ndk配置
android-ndk(android-ndk-r25b-windows.zip)适用于Windows系统
NDK CMake入门基础