在开始本节课,我尝试把项目拷贝到另一台电脑上以便继续工作,但出现了大量的“could not be resolved”问题,尝试包含新的include路径也无法解决该问题,最后删除了项目的Native Support,然后重新添加Native Support才解决。
一、添加和删除Native Support
添加Native Support的方法比较简单,不再多说,删除Native Support的方法如下:
1. 到项目目录下找到.cproject文件并删除。
2. 到项目目录下找到.project文件,用记事本打开并删除以下内容跟cdt有关的内容:
<buildCommand>
???? <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
???? <triggers>clean,full,incremental,</triggers>
???? <arguments>
???? //删除中间内容
???? </arguments>
</buildCommand>
<buildCommand>
???? <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
???? <triggers>full,incremental,</triggers>
???? <arguments>
//删除中间内容
???? </arguments>
</buildCommand>
???? <nature>org.eclipse.cdt.core.cnature</nature>
???? <nature>org.eclipse.cdt.core.ccnature</nature>
???? <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
???? <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
二、在Android中添加线程
与PC端类似,为了使FFmpeg运行起来不影响UI,在Android中也需要开启新线程单独运行FFmpeg。我们可以将init函数修改如下并添加与PC端程序同名的函数以使二者保持一致:
std::string fmlp::init() {
??? pthread_attr_t attr;
??? pthread_attr_init(&attr);
??? pthread_attr_setdetachstate(&attr, 1);
??? void *para;
??? threadID = pthread_create(&runFFmpegThread, &attr, runFFmpegThreadProc,para);
??? return "Hello fmlp...";
}
void *fmlp::runFFmpegThreadProc(void * lpParam) {
??? fmlp *pThis = (fmlp*)lpParam;
??? pThis->runFFmpeg();
}
int fmlp::runFFmpeg() {
??? return 0;
}
三、架起java与c++互通的桥梁
在上面的init函数中,我们可以将字符串"Hello fmlp..."通过Native调用的方式返回给java,但在实际的开发中,还需要将线程中的相关信息返回给java以判断子线程是否正常运行。为了更方便的实现java与c++间的相互通信,可以在demo.cpp中添加以下代码:
jobject mainActivityObj;
JavaVM *jvm;
fmlp *myFmlp;
extern "C" {
// 获取 javaVM
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *javaVm, void *pVoid) {
??? jvm = javaVm;
??? return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL Java_com_example_demo_MainActivity_sendActivityToNative(JNIEnv *env, jobject obj) {
??? mainActivityObj = env->NewGlobalRef(obj);
}
JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_initFmlp(JNIEnv *env, jobject obj) {
myFmlp=new fmlp();
myFmlp->jvm=jvm;
myFmlp->mainActivityObj=mainActivityObj;
string str=myFmlp->init();
return env->NewStringUTF(str.c_str());
}
修改fmlp.cpp将相关信息返回到主界面:
int fmlp::runFFmpeg() {
JNIEnv *env = NULL;
jint result = pThis->jvm->AttachCurrentThread(&env, 0);
if (result != JNI_OK) {
??? return 0;
}
jclass mainActivityClass = env->GetObjectClass(pThis->mainActivityObj);
const char *showSig = "(Ljava/lang/String;)V";
jmethodID show = env->GetMethodID(mainActivityClass, "disMsgFromFmlp", showSig);
env->CallVoidMethod(pThis->mainActivityObj, show,(*env).NewStringUTF("runFFmpeg..."));
return 0;
}
调试运行,能正确返回信息" runFFmpeg......"则表示程序运行正常。