作为一名Android高级工程师,会用NDK是必须的,大家都知道NDK是android的c和c++的工具集,
由于c和c++的运行速度远远高于java而且很难被反编译,所以当android需要实现高速算法而且算
法技术保密性比较高的时候,最佳方式就是通过android ndk用java调c来实现。
C jni代码
#include <jni.h>
#include <string>
#include <math.h>
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
//堆排序heapSort函数声明
void swap(jint* data, int i, int j);
void buildMaxHeap(jint* data, int lastIndex);
//快速排序quickSort函数声明
int getMiddle(jint* list, int low, int high);
void quickSort(jint* list, int low, int high);
void quick(jint* arr,int len);
void sort(JNIEnv *env,int len,jint * data, int left, int right);
void merge(JNIEnv *env,jint * data,int len, int left, int center, int right);
JNIEXPORT jstring JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_stringFromJNI(
JNIEnv *env, jobject jobject) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: insertSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_insertSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
int temp=0;
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
for(int i=1;i<len;i++){
int j=i-1;
temp=array[i];
for(;j>=0&&temp<array[j];j--){
array[j+1]=array[j]; //将大于temp的值整体后移一个单位
}
array[j+1]=temp;
}
//新建一个jintArray对象
jintArray intArray=env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint* int_arr_temp = env->GetIntArrayElements(intArray,NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray,0,len,array);
for(int i=0;i<len;i++){
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d",array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: shellSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_shellSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
double d1=len;
int temp=0;
while(true) {
d1 = ceil(d1 / 2);
int d = (int) d1;
for (int x = 0; x < d; x++) {
for (int i = x + d; i < len; i += d) {
int j = i - d;
temp = array[i];
for (; j >= 0 && temp < array[j]; j -= d) {
array[j + d] = array[j];
}
array[j + d] = temp;
}
}
if (d == 1) {
break;
}
}
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for (int i = 0; i < len; i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: selectSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_selectSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
int position=0;
for(int i=0;i<len;i++){
int j=i+1;
position=i;
int temp=array[i];
for(;j<len;j++){
if(array[j]<temp){
temp=array[j];
position=j;
}
}
array[position]=array[i];
array[i]=temp;
}
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: heapSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_heapSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
int arrayLength=len;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆
buildMaxHeap(array,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(array,0,arrayLength-1-i);
}
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
void swap(jint* data, int i, int j) {
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
//对data数组从0到lastIndex建大顶堆
void buildMaxHeap(jint* data, int lastIndex) {
//从lastIndex处节点(最后一个节点)的父节点开始
for(int i=(lastIndex-1)/2;i>=0;i--){
//k保存正在判断的节点
int k=i;
//如果当前k节点的子节点存在
while(k*2+1<=lastIndex){
//k节点的左子节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex<lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}
}
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: bubbleSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_bubbleSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
int temp=0;
for(int i=0;i<len;i++){
for(int j=0;j<len-1-i;j++){
if(array[j]>array[j+1]){
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: quickSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_quickSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
quick(array,len);
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
int getMiddle(jint* list, int low, int high) {
int tmp =list[low]; //数组的第一个作为中轴
while (low < high){
while (low < high&& list[high] >= tmp) {
high--;
}
list[low] =list[high]; //比中轴小的记录移到低端
while (low < high&& list[low] <= tmp) {
low++;
}
list[high] =list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
void quickSort(jint* list, int low, int high) {
if (low < high){
int middle =getMiddle(list, low, high); //将list数组进行一分为二
quickSort(list, low, middle - 1); //对低字表进行递归排序
quickSort(list,middle + 1, high); //对高字表进行递归排序
}
}
void quick(jint* arr,int len) {
if (len > 0) { //查看数组是否为空
quickSort(arr,0, len - 1);
}
}
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: mergingSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_mergingSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
//sort(env,len,array,0,len-1);
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
void sort(JNIEnv *env,int len,jint * data, int left, int right) {
if(left<right){
//找出中间索引
int center=(left+right)/2;
//对左边数组进行递归
sort(env,len,data,left,center);
//对右边数组进行递归
sort(env,len,data,center+1,right);
//合并
merge(env,data,len,left,center,right);
}
}
void merge(JNIEnv *env,jint * data,int len, int left, int center, int right) {
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *tmpArr = env->GetIntArrayElements(intArray, NULL);
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
//int [] tmpArr=new int[len];
int mid=center+1;
//third记录中间数组的索引
int third=left;
int tmp=left;
while(left<=center&&mid<=right){
//从两个数组中取出最小的放入中间数组
if(data[left]<=data[mid]){
tmpArr[third++]=data[left++];
}else{
tmpArr[third++]=data[mid++];
}
}
//剩余部分依次放入中间数组
while(mid<=right){
tmpArr[third++]=data[mid++];
}
while(left<=center){
tmpArr[third++]=data[left++];
}
//将中间数组中的内容复制回原数组
while(tmp<=right){
data[tmp]=tmpArr[tmp++];
}
}
*/
/*
* Class: myndk_frank_com_myndkdemo_MainActivity
* Method: radixSort
* Signature: ([I)Ljava/lang/String;
*/
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_radixSort
(JNIEnv *env, jobject jobject, jintArray jintarray){
//获取Java传递下来数组的长度
jsize len = env->GetArrayLength(jintarray);
jint *array=env->GetIntArrayElements(jintarray,NULL);
//sort(array);
//新建一个jintArray对象
jintArray intArray = env->NewIntArray(len);
//获取jint_arr_temp对象的指针
jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
//将java数组区复制到C数组区
// env->GetIntArrayRegion(intArray,0,len,array);
env->SetIntArrayRegion(intArray, 0, len, array);
for(int i=0;i<len;i++) {
__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
}
__android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");
return intArray;
}
/*
void sort(jint * array){
//首先确定排序的趟数;
int max=array[0];
for(inti=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}
int time=0;
//判断位数;
while(max>0){
max/=10;
time++;
}
//建立10个队列;
List<ArrayList> queue=newArrayList<ArrayList>();
for(int i=0;i<10;i++){
ArrayList<Integer>queue1=new ArrayList<Integer>();
queue.add(queue1);
}
//进行time次分配和收集;
for(int i=0;i<time;i++){
//分配数组元素;
for(intj=0;j<array.length;j++){
//得到数字的第time+1位数;
int x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10, i);
ArrayList<Integer>queue2=queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count=0;//元素计数器;
//收集队列元素;
for(int k=0;k<10;k++){
while(queue.get(k).size()>0){
ArrayList<Integer>queue3=queue.get(k);
array[count]=queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}
*/
#ifdef __cplusplus
}
#endif
Android java代码
package myndk.frank.com.myndkdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
int numbers[]={49,38,65,97,76,13,27};
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv0 = (TextView) findViewById(R.id.sample_text0);
TextView tv1 = (TextView) findViewById(R.id.sample_text1);
TextView tv2 = (TextView) findViewById(R.id.sample_text2);
TextView tv3 = (TextView) findViewById(R.id.sample_text3);
TextView tv4 = (TextView) findViewById(R.id.sample_text4);
TextView tv5 = (TextView) findViewById(R.id.sample_text5);
TextView tv6 = (TextView) findViewById(R.id.sample_text6);
TextView tv7 = (TextView) findViewById(R.id.sample_text7);
TextView tv8 = (TextView) findViewById(R.id.sample_text8);
String numStr0="";
for(int i=0;i<numbers.length;i++){
numStr0=numStr0+numbers[i]+",";
}
tv0.setText("原数列 :"+numStr0);
int nums1[]=insertSort(numbers);
String numStr1="";
for(int i=0;i<nums1.length;i++){
numStr1=numStr1+nums1[i]+",";
}
tv1.setText("直接插入:"+numStr1);
int nums2[]=shellSort(numbers);
String numStr2="";
for(int i=0;i<nums2.length;i++){
numStr2=numStr2+nums2[i]+",";
}
tv2.setText("希尔排序:"+numStr2);
int nums3[]=selectSort(numbers);
String numStr3="";
for(int i=0;i<nums3.length;i++){
numStr3=numStr3+nums3[i]+",";
}
tv3.setText("选择排序:"+numStr3);
int nums4[]=heapSort(numbers);
String numStr4="";
for(int i=0;i<nums4.length;i++){
numStr4=numStr4+nums4[i]+",";
}
tv4.setText("堆排序 :"+numStr4);
int nums5[]=bubbleSort(numbers);
String numStr5="";
for(int i=0;i<nums5.length;i++){
numStr5=numStr5+nums5[i]+",";
}
tv5.setText("冒泡排序:"+numStr5);
int nums6[]=quickSort(numbers);
String numStr6="";
for(int i=0;i<nums6.length;i++){
numStr6=numStr6+nums6[i]+",";
}
tv6.setText("快速排序:"+numStr6);
int nums7[]=mergingSort(numbers);
String numStr7="";
for(int i=0;i<nums7.length;i++){
numStr7=numStr7+nums7[i]+",";
}
//tv7.setText("归并排序:"+numStr7);
int nums8[]=radixSort(numbers);
String numStr8="";
for(int i=0;i<nums8.length;i++){
numStr8=numStr8+nums8[i]+",";
}
//tv8.setText("基数排序:"+numStr8);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
/**
* 直接插入排序
*/
public native int [] insertSort(int sortNumber[]);
/**
* 希尔排序(最小增量排序)
*/
public native int [] shellSort(int sortNumber[]);
/**
* 简单选择排序
*/
public native int [] selectSort(int sortNumber[]);
/**
* 堆排序
*/
public native int [] heapSort(int sortNumber[]);
/**
* 冒泡排序
*/
public native int [] bubbleSort(int sortNumber[]);
/**
* 快速排序
*/
public native int [] quickSort(int sortNumber[]);
/**
* 归并排序
*/
public native int [] mergingSort(int sortNumber[]);
/**
* 基数排序
*/
public native int [] radixSort(int sortNumber[]);
}