jni使用基础(七)之java调用c事例Demo

简介:

 

 

1.界面:

package com.devchina.ndk3;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class DemoActivity extends Activity {

	static{
		System.loadLibrary("devchina");
	}
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void passInt(View view){
    	JniProvider jni = new JniProvider();
    	int res = jni.add(3, 5);
    	Toast.makeText(this, res+"", 1).show();
    }
    
    public void passString(View view){
    	JniProvider jni = new JniProvider();
    	String res = jni.sayHelloInc("li si");
    	Toast.makeText(this, res+"", 1).show();
    }
    
    public void passIntArr(View view){
    	int [] arr = {1,2,3,4,5,6};
    	JniProvider jni = new JniProvider();
    	int [] cArr = jni.intMethod(arr);
    	for(int i=0;i<arr.length;i++){
    		System.out.println("java arr["+i+"]="+arr[i]);
    	}
    	
    	for(int j=0;j<cArr.length;j++){
    		System.out.println("c arr["+j+"]="+cArr[j]);
    	}
    	
    	
    }
    
}


 

 

2.jni native类

 

package com.devchina.ndk3;

public class JniProvider {
	
	//在c代码中做加法运算
	public native int add(int x,int y);
	//把字符串传给c处理
	public native String sayHelloInc(String s);
	//把java中的数据组c处理
	public native int[] intMethod(int[] iNum);

}


 

3.Android.mk文件

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS) 
 
LOCAL_MODULE    :=devchina
LOCAL_SRC_FILES :=devchina.c

LOCAL_LDLIBS += -llog
 
include $(BUILD_SHARED_LIBRARY)


 

 

4.通过javah生成的.h头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_devchina_ndk3_JniProvider */

#ifndef _Included_com_devchina_ndk3_JniProvider
#define _Included_com_devchina_ndk3_JniProvider
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_devchina_ndk3_JniProvider_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    sayHelloInc
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_devchina_ndk3_JniProvider_sayHelloInc
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    intMethod
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_devchina_ndk3_JniProvider_intMethod
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif


 

 

5.c程序

#include<stdio.h>
#include<jni.h>
#include"com_devchina_ndk3_JniProvider.h"
#include <android/log.h>
#define LOG_TAG "Hello TAG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

//把java中的String轉化成c語言中的數組
char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
{
	 char*   rtn   =   NULL;
	 jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");
	 jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");
	 jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
	 jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
	 jsize   alen   =   (*env)->GetArrayLength(env,barr);
	 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_com_devchina_ndk3_JniProvider_add
  (JNIEnv * env, jobject obj, jint x, jint y){
   LOGI("x = %d,y=%d",x,y);
   return x+y;
}

JNIEXPORT jstring JNICALL Java_com_devchina_ndk3_JniProvider_sayHelloInc
  (JNIEnv * env, jobject obj, jstring jstr){

	char* p = Jstring2CStr(env,jstr);//在堆空间中,长度可变
    LOGI("in c code %s",p);
    char* newstr = " ni hao ";//在栈空间中,长度不可变了
    //字條串連接操作 stracat(dest,source);
    //要求目标的大小是可变的
    return (*env)->NewStringUTF(env,strcat(p,newstr));

}

JNIEXPORT jintArray JNICALL Java_com_devchina_ndk3_JniProvider_intMethod
  (JNIEnv * env, jobject obj, jintArray jArr){
	int len = (*env)->GetArrayLength(env,jArr);
	LOGI("len=%d",len);

	jint* arr = (*env)->GetIntArrayElements(env,jArr,0);//0,不允许拷贝,1,允许拷贝
	int i=0;
	int temp;
	for(;i<len;i++){
		LOGI("arr[%d]=%d",i,*(arr+i));
		//*(arr+i) +=10;
		temp = arr[i]+20;
		(*env)->SetIntArrayRegion(env,jArr,i,1,&temp);
	}
	//释放内存空间
	(*env)->ReleaseIntArrayElements(env,jArr,arr,0);
	return jArr;
}


 

 

6.界面xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加法" 
        android:onClick="passInt"/>
    
     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="字符串拼接" 
        android:onClick="passString"/>
     
      <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="传递intArr" 
        android:onClick="passIntArr"/>

</LinearLayout>


 

 

 代码下载:http://download.csdn.net/detail/hudan2714/4327239

 

 

目录
相关文章
|
22天前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
56 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
5月前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
162 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
2月前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
62 11
|
2月前
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
87 11
|
3月前
|
Java
MQTT(EMQX) - Java 调用 MQTT Demo 代码
MQTT(EMQX) - Java 调用 MQTT Demo 代码
134 0
MQTT(EMQX) - Java 调用 MQTT Demo 代码
|
3月前
|
开发框架 Java Android开发
JNI中调用Java函数
JNI中调用Java函数
24 0
|
3月前
|
开发框架 Java Android开发
JNI中调用Java函数
JNI中调用Java函数
31 0
|
3月前
|
算法 Java Linux
Intellij Java JNI 调用 C++
Intellij Java JNI 调用 C++
34 0
|
5月前
|
安全 Java