本项目是生成静态库libA.a,用libA.a生成libB.a,再用libA.a和libB.a一起生成libC.so动态库。
1.新建一个安卓项目,添加文件夹jni,在jni下添加cpp或者c文件,此cpp或c文件就是用来生成so的源文件。
2.要生成静态库libA.a,要有Android.mk文件和Application.mk,直接在jni目录下添加即可。
Android.mk内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := A//生成的静态库的名字,即libA.a中的A
LOCAL_SRC_FILES := //需要的源文件,依次列开,用空格或tab隔开
include $(BUILD_STATIC_LIBRARY)//生成静态库
Application.mk内容如下:
APP_MODULES :=A//表明生成静态库的名字
3.用静态库libA.a生成libB.a,直接在jni目录下添加Android.mk和Application.mk文件。
Android.mk内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := A
LOCAL_SRC_FILES := libA.a
include $(PREBUILT_STATIC_LIBRARY) //连接方式是静态的
include $(CLEAR_VARS)
LOCAL_MODULE := B//生成的静态库的名字
LOCAL_STATIC_LIBRARIES := A//需要的静态库
LOCAL_SRC_FILES := //需要的源文件
include $(BUILD_STATIC_LIBRARY)//生成静态库
Application.mk的内容和2中的一样。
4.用静态库libA.a和libB.a生成libC.so动态库
只需要Android.mk即可,内容如下:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=A B
LOCAL_SRC_FILES :=libA.a libB.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -lm -llog//在c文件中打log
LOCAL_MODULE :=C//生成的动态库的名字
LOCAL_STATIC_LIBRARIES :=A B//依赖的静态库名字
LOCAL_SRC_FILES:=//所需的源文件
include $(BUILD_SHARED_LIBRARY)
5.生成的动态库在本项目中使用,或者在别的项目中调用。
src中的java文件如何调用:
/*
* 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.example.hellojni;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Hashtable;
import org.apache.http.util.ByteArrayBuffer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
import android.os.Environment;
//import com.android.ide.eclipse.ndk.*;
public class HelloJni extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>}
static {
System.loadLibrary("decode");//加载动态库,动态库要放在bin\ndk\local\armeabi目录下
}
}
6.在windows命令行进入项目的bin\classes路径下,执行javah -d jni com.example.hellojni.HelloJni,前3个单词是包的名字,后一个单词是类名字。
会生成一个头文件,放在jni目录下
7.源文件的接口必须按照如下接口:
jbyteArray Java_com_example_hellojni_HelloJni_fun( JNIEnv* env,
jobject thiz,jstring imagefile)
com_example_hellojni是包名
HelloJni是类名
fun是方法名
8.从java传入字符串给c
const char* jcstr = (const char *)(*env)->GetStringUTFChars(env,imagefile, 0 );//返回指向字符串的 UTF-8 字符数组的指针
//LOGI("%s","MYLOG:BBB");
int length=0;
length= (*env)->GetStringUTFLength(env,imagefile)+1;//以字节为单位返回字符串的 UTF-8 长度
LOGI("%d",length);
char* rtn = (char*)malloc( length );
memcpy(rtn,jcstr,length);
//char* rtn = (char*)malloc( 33 );
//memcpy(rtn,jcstr,33);
char *aaa = rtn;
(*env)->ReleaseStringUTFChars(env, imagefile, jcstr);//通知虚拟机平台相关代码无需再访问 utf
9.如果返回一个自己定义的中文字符串,那么在java中接受是没有问题的,但是我的项目提供的字符串是带中文的而且不知道是什么格式的,和自己定义的字符串不一样,所以 最终决定返回byte数组,在java中转换为中文字符串 ,
unsigned char result[1000] = {0};
memset(result,0,1000);
// unsigned char test[] = "adfadf35345你说什么";
len = strlen(result);
LOGI("len::");
LOGI("%d",len);
jbyteArray data = (*env)->NewByteArray(env,len);// 我这里是byte型数组 1024是数组长度
jbyte* pbuf = (jbyte*)malloc(len);
memcpy(pbuf, result, len);
(*env)->SetByteArrayRegion(env,data, 0, len, pbuf);
LOGI("%s",data);
free(pbuf);
return data;
在java中
String str2 = "";
try {
str2 = new String(res,"GBK");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
即可
ps:c和java的文件环境都是utf-8格式的
10.在c文件打log:
#include <android/log.h>
#define LOG_TAG "logfromc"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
在Android.mk中加入一句:
include $(CLEAR_VARS)//此句下边
LOCAL_LDLIBS := -lm -llog