Android自助餐之Jni(三)动态导入so文件
Android自助餐专栏
Android自助餐之Jni(一)最简单的运行
Android自助餐之Jni(二)静态导入so文件
Android自助餐之Jni(三)动态导入so文件
Android自助餐之Jni(四)在线导入so文件
Android自助餐之Jni(五)进阶
Android自助餐之Jni(六)NDK入门
下载完整源代码
拷贝so文件
假设so文件放在assets目录下
创建assets文件夹:在main文件夹上右键->new->folder->AssetsFolder
将so文件及其文件夹(armeabi等)复制到assets文件夹
创建jni对应类
本实例已知c文件内容如下
JNIEXPORT jstring JNICALL
Java_com_xmh_jni_JniUtil_getResult(JNIEnv *env,jobject obj,jstring value){
char * str;
str=(*env)->GetStringUTFChars(env,value,NULL);
sprintf(str,"%s-_-%s",str,str);
return (*env)->NewStringUTF(env, str);
}
因此所创建的类完整类名为:com.xmh.jni.JniUtil。文件内容如下
public class JniUtil {
/*封装native方法,先加载so文件后调用native方法*/
public String getResult(Context context,String value){
loadLibrary(context);
return getResult(value);
}
/*加载so文件*/
private void loadLibrary(Context context) {
try {
//获取文件输入流
InputStream inStream = context.getAssets().open("armeabi/libJniLibDemo.so");
//获取文件输出流:目录是/data/data/app包名/app_lib/(该目录为app私有目录,具有执行权限)
File libsDir = context.getDir("libs", Context.MODE_PRIVATE);
String soFilePath=libsDir.getAbsolutePath() + "/libJniLibDemo.so";
FileOutputStream outStream = new FileOutputStream(soFilePath);
//使用两个流复制文件
FileUtil.copyFile(inStream,outStream);
//加载so文件
System.load(soFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
public native String getResult(String value);
}
FileUtil类
该类用于文件复制
public class FileUtil {
public static void copyFile(InputStream inStream, FileOutputStream outStream) throws IOException {
int bytesum = 0;
int byteread = 0;
byte[] buffer = new byte[1444];
int length;
while ( (byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
System.out.println(bytesum);
outStream.write(buffer, 0, byteread);
}
outStream.flush();
}
}
在需要的地方调用
new JniUtil().getResult(this,"xmh");