初学Android中间件的开发,总结几天学习的内容
Android软件层次结构包括了一个操作系统(OS),中间件(MiddleWare)和应用程序(Application),中间件包括了各种库(静态的动态的)以及应用程序框架(framework),这里主要介绍中间件中库的开发,使用JAVA调用C库,封装成led.so的库文件(针对led灯)。Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
新建文件夹Jni存放Android.mk和led.c
Jni
├── Android.mk
└── led.c
Android.mk
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := led.c
LOCAL_MODULE := libled
LOCAL_SHARED_LIBRARIES := libc
include $(BUILD_SHARED_LIBRARY)
path默认为my-dir,files位led.c,module为生成之后的库文件名libled.so共享库位libc
led.c
#include <jni.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//jar com/lc/Led.java
//与framework中的包名类名函数名一致
static int fd;
static int flag = 0;
//JNIEXPORT 函数返回值类型 JNICALL Java_包名_类名_函数名
JNIEXPORT jstring JNICALL Java_com_lc_Led_ledOpen //在JAVA中调用C库函数,打开led设备
(JNIEnv *env, jobject obj)
{
if(!flag){
fd = open("/dev/myled", O_RDWR);//打开设备myled,设备的创建由驱动程序完成
if(fd < 0)
return (*env)->NewStringUTF(env, "open /dev/myled failed");//返回错误信息
flag = 1;
return (*env)->NewStringUTF(env, "open /dev/myled success");返回成功打开设备信息}
return (*env)->NewStringUTF(env, "led already open");
}
JNIEXPORT jstring JNICALL Java_com_lc_Led_ledClose //关闭led设备
(JNIEnv *env, jobject obj)
{
if(flag){close(fd);
flag = 0;
return (*env)->NewStringUTF(env, "close /dev/myled success");
}
return (*env)->NewStringUTF(env, "led already close");
}
JNIEXPORT jstring JNICALL Java_com_lc_Led_ledWrite //对led进行操作,即控制了led的开关
(JNIEnv *env, jobject obj, jstring cmd) //用户传led状态参数cmd
{
int ret;
char *s = (*env)->GetStringUTFChars(env, cmd, 0);//把JAVA参数cmd转换为C字符串
if(flag){
ret = write(fd, s, 3);
(*env)->ReleaseStringUTFChars(env, cmd, s);//释放为cmd申请的空间
if(ret < 0)
return (*env)->NewStringUTF(env, "led write failed");
else
return (*env)->NewStringUTF(env, "led write success");
}
return (*env)->NewStringUTF(env, "led not open");
}
JNIEXPORT jstring JNICALL Java_com_lc_Led_ledRead //读取led状态
(JNIEnv *env, jobject obj)
{
int ret;
char buf[64];
if(flag){ret = read(fd, buf, 63);
if(ret < 0){
return (*env)->NewStringUTF(env, "led read failed");
}
else{
buf[ret] = 0;
return (*env)->NewStringUTF(env, buf); //读取led状态并存如buf}}
return (*env)->NewStringUTF(env, "led not open");
}
在Andriod源码中使用:mmm <path你Jni所在路径>,能生成libled.so的库文件