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

第21课 在Android Native开发中架起java与c++互通的桥梁-LMLPHP

01-25 07:51