android调用SO

来源:互联网 发布:node express项目 编辑:程序博客网 时间:2024/05/29 10:59

android调用so

android虚拟机不能直接调用底层设备,我们如果要对底层设备进行调用就需要用到so.

so使用C语言或C++编写完成,使用ndk进行编译,直接运行在linux内核中.

按jni调用so时基本类型可以直接交互,jstring使用时有点麻烦,所以我做一个jstring和char*进行转换的例子.

第一步:

工程根目录下创建jni目录.libs目录不用手动建立.


注意:这里使用ndk_R7所以不需要用jdk去生成C文件头.

第二部:

java编写接口文件(Device.java)

public class Device { static {        System.loadLibrary("device");    } public native String deviceTestString(String test);}
方法名必须使用native关键字声明,并且必须使用system.loadLibrary("SO文件名")承载c类库;

第三部:

编写C文件(devices.c)

这里编写的c代码属于linux C范畴.

#include <string.h>#include <jni.h>char* jstringTostrM(JNIEnv* env, jstring jstr){           char* pStr = NULL;    jclass     jstrObj   = (*env)->FindClass(env, "java/lang/String");    jstring    encode    = (*env)->NewStringUTF(env, "utf-8");    jmethodID  methodId  = (*env)->GetMethodID(env, jstrObj, "getBytes", "(Ljava/lang/String;)[B");    jbyteArray byteArray = (jbyteArray)(*env)->CallObjectMethod(env, jstr, methodId, encode);    jsize      strLen    = (*env)->GetArrayLength(env, byteArray);    jbyte      *jBuf     = (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);    if (jBuf > 0)    {        pStr = (char*)malloc(strLen + 1);        if (!pStr)        {            return NULL;        }        memcpy(pStr, jBuf, strLen);        pStr[strLen] = 0;    }    (*env)->ReleaseByteArrayElements(env, byteArray, jBuf, 0);    return pStr;}jstring Java_com_jack_Device_deviceTestString(JNIEnv* env,jclass clazz,jstring path){//system("echo devices.so test > /sdcard/log/log.txt");char * test = jstringTostrM(env,path);return (*env)->NewStringUTF(env, test);}

注意:C的函数命名规则:Java是jni标准必须有,com_jack_Device是Device.java文件的全名,再下来才是C函数名

jstringTostrM函数必须写在Java_com_jack_Device_deviceTestString函数前,如果不是必须要C文件开头进行声明.

声明代码:

char* jstringTostrM(JNIEnv* env, jstring jstr);
第四步:编写Android.mk和编译

android.mk文件如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := deviceLOCAL_SRC_FILES := device.cinclude $(BUILD_SHARED_LIBRARY)
如果要编译成可执行文件
include $(BUILD_EXECUTABLE)

编译:


第五步:编写java代码进行C函数调用:

 Device device = new Device();        String test = device.deviceTestString("你好~!!!");        Toast toast = Toast.makeText(Jack_ndk_jstringActivity.this, test, Toast.LENGTH_LONG);        toast.setGravity(Gravity.TOP,0,150);        toast.show();        TextView text = (TextView) findViewById(R.id.text1);        text.setText(test);
注意:最好在AndroidManifest.xml文件中加入文件控制控制权限.

  <!-- 文件权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
源码下载:

http://115.com/file/belu6068

原创粉丝点击