目前,已经搞清楚了ndk文件的编写及调用。如果JNI是cpp文件,则与c文件有所不同,需要用extern c处理一下。其他则无不同。
现在可以调到库中的函数,线程创建也正常,但是设备启动时出现了异常。有以下怀疑:原dms程序是在命令行下运行,输入的字符及log的输出有个根据地(shell),但是如果用ui启动,则失去了这个根据地。
需要在Build.scons中做以下配置:
LibraryModule(name = 'dms', build_source_files = {'Apps/dms':'dmsJNI.cpp'}, linked_modules = ['Platinum', 'PltMediaServer', 'PltMediaRenderer', 'PltMediaConnect'], included_modules = ['Platinum', 'PltMediaServer', 'PltMediaRenderer', 'PltMediaConnect'], source_root = 'Source', shared = True, install = True)
需要生成库的文件:dmsJNI.cpp:
#include <jni.h> #include "Neptune.h" #include "Platinum.h" #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <unistd.h> NPT_SET_LOCAL_LOGGER("platinum.media.server") PLT_UPnP upnp; PLT_DeviceHostReference device; pthread_t thread; static void* start_dms(void* thread_param) { // setup Neptune logging NPT_LogManager::GetDefault().Configure("plist:.level=INFO;.handlers=ConsoleHandler;.ConsoleHandler.colors=off;.ConsoleHandler.filter=42"); NPT_LOG_INFO("baojinyu--------dms_lib---->start_dms.\n"); device = new PLT_FileMediaServer("/data/local", "UPnP Media Server"); NPT_List<NPT_IpAddress> list; PLT_UPnPMessageHelper::GetIPAddresses(list); //NPT_String ip = list.GetFirstItem()->ToString(); device->m_ModelDescription = "Platinum Media Server"; device->m_ModelURL = "http://www.plutinosoft.com/"; device->m_ModelNumber = "1.0"; device->m_ModelName = "Platinum Media Server"; device->m_Manufacturer = "Plutinosoft"; device->m_ManufacturerURL = "http://www.plutinosoft.com/"; upnp.AddDevice(device); upnp.Start(); //NPT_CHECK_SEVERE(upnp.Start()); while(1) { } return NULL; } static int stop_dms() { NPT_LOG_INFO("baojinyu--------dms_lib---->stop_dms.\n"); //printf("baojinyu--------dms_lib---->stop_dms.\n"); upnp.Stop(); return 0; } //------------ extern "C" { JNIEXPORT int JNICALL Java_com_android_dlna_dms_dmsThreadBegin(JNIEnv *env, jobject obj); JNIEXPORT int JNICALL Java_com_android_dlna_dms_dmsThreadEnd(JNIEnv *env, jobject obj); }; JNIEXPORT int JNICALL Java_com_android_dlna_dms_dmsThreadBegin(JNIEnv *env, jobject obj) { int retval; retval = pthread_create(&thread, NULL, start_dms, NULL); if(retval != 0) { NPT_LOG_INFO("create thread fail!\n"); //printf("create thread fail!\n"); return -1; //exit会导致整个进程的所有线程都终止。 } else { NPT_LOG_INFO("pthread_create success.\n"); } return 0; } JNIEXPORT int JNICALL Java_com_android_dlna_dms_dmsThreadEnd(JNIEnv *env, jobject obj) { stop_dms(); pthread_exit(NULL);//终止线程自己 //pthread_cancel(thread);//终止同一进程中的其他线程,未定义? NPT_LOG_INFO("thread exit!\n"); return 0; }
/** * file: dms.java * {@hide} */ package com.android.dlna; public class dms { static { System.loadLibrary("dms"); } public static native int dmsThreadBegin(); public static native int dmsThreadEnd(); }
package com.android.dlna;函数的调用很简单:
dms.dmsThreadBegin(); dms.dmsThreadEnd();
小结一下,原来内容就这么一点。
原来混乱不清的很多问题都搞清楚了。
下一步的工作是搞清楚设备启动前后的所有奥秘。