- 实现一个文件的拷贝操作通过JNI 调用
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.Thread;
public class LocalFileProduce extends Thread implements IDataProduce
{
public File file = null;
public FileInputStream input = null;
@Override
public void produceData() {
byte[] data = new byte[1024];
file = new File("/storage/emulated/0/1/123.mp4");
try {
input = new FileInputStream(file);
int n = -1;
while((n = input.read(data, 0, data.length)) != -1){
produceData(data, n);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
produceData();
stopWork();
}
public native void produceData(byte[] data, int len);
public native void stopWork();
}
2.在C++开启线程,异步写文件
#include <jni.h>
#include <string>
#include "AndroidLog.h"
#include "pthread.h"
#include "queue"
#include "unistd.h"
#include <sys/stat.h>
#include <sys/time.h>
#include <stdlib.h>
#include <fcntl.h>
pthread_t produc;
pthread_t custom;
pthread_mutex_t mutex;
pthread_cond_t cond;
bool isStop = false;
struct MData{
jbyte* data;
int len;
};
std::queue<MData> queue;
static const char* const filename = "/storage/emulated/0/1/123_dat.mp4";
int fd = 0;
extern "C"
JNIEXPORT void JNICALL
Java_com_syf_videoplay_LocalFileProduce_produceData(JNIEnv *env, jobject thiz, jbyteArray data,
jint len) {
//jbyte* bytedata = env->GetByteArrayElements(data, 0); //C++ 写法
jsize size = env->GetArrayLength(data);
if(size != len)
size = len;
MData mData;
jbyte* dst = (jbyte*) malloc(size* sizeof(jbyte));
memset(dst, 0, sizeof(jbyte)*size);
env->GetByteArrayRegion(data, 0, size, dst);
//memcpy(bytedata,dst, size);
//mData.data = bytedata;
mData.data = dst;
mData.len = size;
pthread_mutex_lock(&mutex);
queue.push(mData);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
usleep(1);
//env->ReleaseByteArrayElements(data, bytedata,JNI_COMMIT);
}
void *customRun(void *data){
DEBUG__TIME0;
while(!isStop){
pthread_mutex_lock(&mutex);
if(queue.size() > 0){
MData tmp = queue.front();
if(fd != 0){
write(fd, tmp.data, tmp.len);
free(tmp.data);
tmp.data = NULL;
}
queue.pop();
}else {
//LOGD("custom wait");
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
usleep(1);
}
DEBUG__TIME1;
//%4.4f 前面4表示总数字位为4,不满4则右对齐,后面的4表示小数点后保留4位有效数字
LOGD("Running times:detect facedetect %4.4fms" , RUN_TIME(TIME1 - TIME0));
pthread_exit(&custom);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_syf_videoplay_LocalFileProduce_stopWork(JNIEnv *env, jobject thiz) {
pthread_mutex_lock(&mutex);
isStop = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
close(fd);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_syf_videoplay_MainActivity_perpareWork(JNIEnv *env, jobject thiz) {
fd = open(filename, O_CREAT | O_RDWR, 0666);
LOGD("file fd %d", fd);
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
//pthread_create(&produc, NULL, produceRun, NULL);
pthread_create(&custom, NULL, customRun, NULL);
}