在开始本节课,我尝试把项目拷贝到另一台电脑上以便继续工作,但出现了大量的“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" {// 获取 javaVMJNIEXPORT 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......"则表示程序运行正常。