void* SkiaAndroidApp::pthread_main(void* arg) { SkDebugf("pthread_main begins"); auto skiaAndroidApp = (SkiaAndroidApp*)arg; // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); pipe(skiaAndroidApp->fPipes); ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT, message_callback, skiaAndroidApp); skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp); double currentTime = 0.0; double previousTime = 0.0; while (true) { const int ident = ALooper_pollAll(0, nullptr, nullptr, nullptr); if (ident >= 0) { SkDebugf("Unhandled ALooper_pollAll ident=%d !", ident); } else { previousTime = currentTime; currentTime = now_ms(); skiaAndroidApp->fApp->onIdle(currentTime - previousTime); } } SkDebugf("pthread_main ends"); return nullptr; }
static void* android_app_entry(void* param) { struct android_app* android_app = (struct android_app*)param; android_app->config = AConfiguration_new(); AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); print_cur_config(android_app); android_app->cmdPollSource.id = LOOPER_ID_MAIN; android_app->cmdPollSource.app = android_app; android_app->cmdPollSource.process = process_cmd; android_app->inputPollSource.id = LOOPER_ID_INPUT; android_app->inputPollSource.app = android_app; android_app->inputPollSource.process = process_input; ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, &android_app->cmdPollSource); android_app->looper = looper; pthread_mutex_lock(&android_app->mutex); android_app->running = 1; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); android_main(android_app); android_app_destroy(android_app); return NULL; }
JNIEXPORT void JNICALL Java_net_jlekstrand_wheatley_wayland_Compositor_addToLooperNative(JNIEnv *env, jclass cls, jlong nativeHandle) { struct wheatley_compositor *wc = (struct wheatley_compositor *)(intptr_t)nativeHandle; ALooper *looper; if (wc->looper) { jni_util_throw_by_name(env, "java/lang/IllegalStateException", "Compositor already assigned to a looper"); return; } looper = ALooper_forThread(); if (looper == NULL) { jni_util_throw_by_name(env, "java/lang/RuntimeException", "Current thread does not have a Looper"); return; } ALooper_addFd(looper, wl_event_loop_get_fd(wl_display_get_event_loop(wc->display)), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT, wheatley_compositor_ALooper_func, wc); wc->looper = looper; }
static void frontend_android_init(void *data) { JNIEnv *env; ALooper *looper; jclass class = NULL; jobject obj = NULL; struct android_app* android_app = (struct android_app*)data; if (!android_app) return; looper = (ALooper*)ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL); android_app->looper = looper; slock_lock(android_app->mutex); android_app->running = 1; scond_broadcast(android_app->cond); slock_unlock(android_app->mutex); memset(&g_android, 0, sizeof(g_android)); g_android = (struct android_app*)android_app; RARCH_LOG("Waiting for Android Native Window to be initialized ...\n"); while (!android_app->window) { if (!android_run_events(android_app)) { frontend_android_deinit(android_app); frontend_android_shutdown(android_app); return; } } RARCH_LOG("Android Native Window initialized.\n"); env = jni_thread_getenv(); if (!env) return; GET_OBJECT_CLASS(env, class, android_app->activity->clazz); GET_METHOD_ID(env, android_app->getIntent, class, "getIntent", "()Landroid/content/Intent;"); CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent); #if 0 GET_METHOD_ID(env, android_app->hasPendingIntent, class, "hasPendingIntent", "()Z"); GET_METHOD_ID(env, android_app->clearPendingIntent, class, "clearPendingIntent", "()V"); GET_METHOD_ID(env, android_app->getPendingIntentConfigPath, class, "getPendingIntentConfigPath", "()Ljava/lang/String;"); GET_METHOD_ID(env, android_app->getPendingIntentLibretroPath, class, "getPendingIntentLibretroPath", "()Ljava/lang/String;"); GET_METHOD_ID(env, android_app->getPendingIntentFullPath, class, "getPendingIntentFullPath", "()Ljava/lang/String;"); GET_METHOD_ID(env, android_app->getPendingIntentIME, class, "getPendingIntentIME", "()Ljava/lang/String;"); #endif GET_OBJECT_CLASS(env, class, obj); GET_METHOD_ID(env, android_app->getStringExtra, class, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); }
void *cxAndroid::AndroidEntry(void *data) { cxAndroid *app = (cxAndroid *)data; AConfiguration_fromAssetManager(app->config, app->activity->assetManager); app->cmd.id = LOOPER_ID_MAIN; app->cmd.app = app; app->cmd.process = cxAndroid::cxAndroidExec; app->input.id = LOOPER_ID_INPUT; app->input.app = app; app->input.process = cxAndroid::cxAndroidInputExec; app->looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(app->looper, app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,&app->cmd); pthread_mutex_lock(&app->mutex); app->running = true; pthread_cond_broadcast(&app->cond); pthread_mutex_unlock(&app->mutex); app->cxAndroidMain(); pthread_mutex_lock(&app->mutex); if (app->inputQueue != NULL) { AInputQueue_detachLooper(app->inputQueue); app->inputQueue = NULL; } AConfiguration_delete(app->config); app->config = NULL; app->destroyed = true; pthread_cond_broadcast(&app->cond); pthread_mutex_unlock(&app->mutex); return data; }
void* SkiaAndroidApp::pthread_main(void* arg) { SkDebugf("pthread_main begins"); auto skiaAndroidApp = (SkiaAndroidApp*)arg; // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); pipe(skiaAndroidApp->fPipes); ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT, message_callback, skiaAndroidApp); int ident; int events; struct android_poll_source* source; skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp); while ((ident = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) { SkDebugf("ALooper_pollAll ident=%d", ident); } return nullptr; }
Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback) : mId(id), mFd(fd), mDeviceCallback(std::move(callback)) { ALooper* aLooper = ALooper_forThread(); if (aLooper == NULL) { LOGE("Could not get ALooper, ALooper_forThread returned NULL"); aLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); } ALooper_addFd(aLooper, fd, 0, ALOOPER_EVENT_INPUT, handleLooperEvents, reinterpret_cast<void*>(this)); }
static void* AndroidEventThreadWorker( void* param ) { struct android_app* state = (struct android_app*)param; FPlatformProcess::SetThreadAffinityMask(FPlatformAffinity::GetMainGameMask()); FPlatformMisc::LowLevelOutputDebugString(L"Entering event processing thread engine entry point"); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, state->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, &state->cmdPollSource); state->looper = looper; FPlatformMisc::LowLevelOutputDebugString(L"Prepared looper for event thread"); //Assign the callbacks state->onAppCmd = OnAppCommandCB; state->onInputEvent = HandleInputCB; FPlatformMisc::LowLevelOutputDebugString(L"Passed callback initialization"); // Acquire sensors SensorManager = ASensorManager_getInstance(); if (NULL != SensorManager) { // Register for the various sensor events we want. Some // may return NULL indicating that the sensor data is not // available in the device. For those empty data will eventually // get fed into the motion events. SensorAccelerometer = ASensorManager_getDefaultSensor( SensorManager, ASENSOR_TYPE_ACCELEROMETER); SensorGyroscope = ASensorManager_getDefaultSensor( SensorManager, ASENSOR_TYPE_GYROSCOPE); // Create the queue for events to arrive. SensorQueue = ASensorManager_createEventQueue( SensorManager, state->looper, LOOPER_ID_USER, HandleSensorEvents, NULL); } FPlatformMisc::LowLevelOutputDebugString(L"Passed sensor initialization"); //continue to process events until the engine is shutting down while (!GIsRequestingExit) { // FPlatformMisc::LowLevelOutputDebugString(L"AndroidEventThreadWorker"); AndroidProcessEvents(state); sleep(EventRefreshRate); // this is really 0 since it takes int seconds. } UE_LOG(LogAndroid, Log, TEXT("Exiting")); return NULL; }
void message_dispatcher::prepare() { scoped_lock lock(m_mutex); m_looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); if (!m_looper) throw std::runtime_error("cannot create the internal looper"); ALooper_addFd(m_looper, m_readfd, MSG_ID_SYSTEM, ALOOPER_EVENT_INPUT, NULL, NULL); if (m_iqueue) { attach_queue(m_iqueue); } }
// Called before main() to initialize JNI bindings static void orxAndroid_Init(JNIEnv* mEnv, jobject jActivity) { LOGI("orxAndroid_Init()"); jclass objClass; orxAndroid_JNI_SetupThread(); sstAndroid.mActivity = mEnv->NewGlobalRef(jActivity); objClass = mEnv->FindClass("org/orx/lib/OrxActivity"); sstAndroid.midGetRotation = mEnv->GetMethodID(objClass, "getRotation","()I"); sstAndroid.midGetDeviceIds = mEnv->GetMethodID(objClass, "getDeviceIds", "()[I"); if(!sstAndroid.midGetRotation || !sstAndroid.midGetDeviceIds) { __android_log_print(ANDROID_LOG_WARN, "Orx", "Couldn't locate Java callbacks, check that they're named and typed correctly"); } // setup AssetManager jmethodID midGetAssets = mEnv->GetMethodID(objClass, "getAssets", "()Landroid/content/res/AssetManager;"); jobject jAssetManager = mEnv->CallObjectMethod(jActivity, midGetAssets); sstAndroid.jAssetManager = mEnv->NewGlobalRef(jAssetManager); sstAndroid.poAssetManager = AAssetManager_fromJava(mEnv, sstAndroid.jAssetManager); mEnv->DeleteLocalRef(objClass); mEnv->DeleteLocalRef(jActivity); mEnv->DeleteLocalRef(jAssetManager); sstAndroid.looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(sstAndroid.looper, sstAndroid.pipeCmd[0], LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL); ALooper_addFd(sstAndroid.looper, sstAndroid.pipeKeyEvent[0], LOOPER_ID_KEY_EVENT, ALOOPER_EVENT_INPUT, NULL, NULL); ALooper_addFd(sstAndroid.looper, sstAndroid.pipeTouchEvent[0], LOOPER_ID_TOUCH_EVENT, ALOOPER_EVENT_INPUT, NULL, NULL); ALooper_addFd(sstAndroid.looper, sstAndroid.pipeJoystickEvent[0], LOOPER_ID_JOYSTICK_EVENT, ALOOPER_EVENT_INPUT, NULL, NULL); LOGI("orxAndroid_Init() finished!"); }
void* SkiaAndroidApp::pthread_main(void* arg) { SkDebugf("pthread_main begins"); auto skiaAndroidApp = (SkiaAndroidApp*)arg; // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); pipe(skiaAndroidApp->fPipes); ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT, message_callback, skiaAndroidApp); static const char* gCmdLine[] = { "viewer", // TODO: figure out how to use am start with extra params to pass in additional arguments at // runtime. Or better yet make an in app switch to enable // "--atrace", }; skiaAndroidApp->fApp = Application::Create(SK_ARRAY_COUNT(gCmdLine), const_cast<char**>(gCmdLine), skiaAndroidApp); while (true) { const int ident = ALooper_pollAll(0, nullptr, nullptr, nullptr); if (ident >= 0) { SkDebugf("Unhandled ALooper_pollAll ident=%d !", ident); } else { skiaAndroidApp->fApp->onIdle(); } } SkDebugf("pthread_main ends"); return nullptr; }
JNIEXPORT jboolean JNICALL Java_edu_ucla_nesl_sigma_base_SigmaJNI_waitForMessage (JNIEnv *env, jclass _class, jint fd) { ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALOGD("waitForMessage: pollOnce looper@%d fd@%d", (int)looper, fd); ALooper_addFd(looper, fd, fd, ALOOPER_EVENT_INPUT, NULL, NULL); int events; int result = ALooper_pollOnce(-1, NULL, &events, NULL); if (result == ALOOPER_POLL_ERROR) { ALOGE("waitForMessage error (errno=%d)", errno); result = -1337; // unknown error, so we make up one return JNI_FALSE; } if (events & ALOOPER_EVENT_HANGUP) { // the other-side has died ALOGE("waitForMessage error HANGUP"); result = -1337; // unknown error, so we make up one return JNI_FALSE; } return JNI_TRUE; ALOGD("waitForMessage: got something."); }
static void *android_app_entry(void *data) { struct android_app* android_app = (struct android_app*)data; android_app->config = AConfiguration_new(); AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); print_cur_config(android_app); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL); android_app->looper = looper; pthread_mutex_lock(&android_app->mutex); android_app->running = 1; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); memset(&g_android, 0, sizeof(g_android)); g_android = android_app; RARCH_LOG("Native Activity started.\n"); rarch_main_clear_state(); while (!android_app->window) { if (!android_run_events(android_app)) goto exit; } rarch_init_msg_queue(); if (!android_app_start_main(android_app)) { g_settings.input.overlay[0] = 0; // threaded video doesn't work right for just displaying one frame g_settings.video.threaded = false; init_drivers(); driver.video_poke->set_aspect_ratio(driver.video_data, ASPECT_RATIO_SQUARE); rarch_render_cached_frame(); sleep(2); goto exit; } if (!g_extern.libretro_dummy) menu_rom_history_push_current(); for (;;) { if (g_extern.system.shutdown) break; else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME)) { load_menu_game_prepare(); // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ... if (load_menu_game()) g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); else { #ifdef RARCH_CONSOLE g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); #else return NULL; #endif } g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME); } else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME)) { driver.input->poll(NULL); if (driver.video_poke->set_aspect_ratio) driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx); if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) audio_start_func(); // Main loop while (rarch_main_iterate()); if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) audio_stop_func(); g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); } else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)) { g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT); while((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? android_run_events(android_app) : menu_iterate()); g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU); } else break; } exit: android_app->activityState = APP_CMD_DEAD; RARCH_LOG("Deinitializing RetroArch...\n"); menu_free(); if (g_extern.config_save_on_exit && *g_extern.config_path) config_save_file(g_extern.config_path); if (g_extern.main_is_init) rarch_main_deinit(); rarch_deinit_msg_queue(); #ifdef PERF_TEST rarch_perf_log(); #endif rarch_main_clear_state(); RARCH_LOG("android_app_destroy!"); if (android_app->inputQueue != NULL) AInputQueue_detachLooper(android_app->inputQueue); AConfiguration_delete(android_app->config); // exit() here is nasty. // pthread_exit(NULL) or return NULL; causes hanging ... // Should probably called ANativeActivity_finsih(), but it's bugged, it will hang our app. exit(0); }
void StAndroidGlue::threadEntry() { if(myJavaVM->AttachCurrentThread(&myThJniEnv, NULL) < 0) { ST_ERROR_LOG("Failed to attach working thread to Java VM"); return; } THE_ANDROID_GLUE = this; StMessageBox::setCallback(msgBoxCallback); myConfig = AConfiguration_new(); AConfiguration_fromAssetManager(myConfig, myActivity->assetManager); updateMonitors(); printConfig(); ALooper* aLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(aLooper, myMsgRead, LooperId_MAIN, ALOOPER_EVENT_INPUT, NULL, &myCmdPollSource); myLooper = aLooper; pthread_mutex_lock(&myMutex); myIsRunning = true; pthread_cond_broadcast(&myCond); pthread_mutex_unlock(&myMutex); // try to load stereo APIs /**jclass aJClass_Real3D = myThJniEnv->FindClass("com/lge/real3d/Real3D"); if(aJClass_Real3D != NULL) { jmethodID aJMet_isStereoDisplayAvailable = myThJniEnv->GetStaticMethodID(aJClass_Real3D, "isStereoDisplayAvailable", "(Landroid/content/Contex;)Z"); postMessage("com.lge.real3d.Real3D !!!"); } jclass aJClass_HTC = myThJniEnv->FindClass("com/htc/view/DisplaySetting"); if(aJClass_HTC != NULL) { jmethodID aJMet_isStereoDisplayAvailable = myThJniEnv->GetStaticMethodID(aJClass_HTC, "setStereoscopic3DFormat", "(Landroid/view/Surface;I)Z"); postMessage("com.htc.view.DisplaySetting !!!"); } jclass aJClass_Sharp = myThJniEnv->FindClass("jp/co/sharp/android/stereo3dlcd/SurfaceController"); if(aJClass_Sharp != NULL) { jmethodID aJMet_setStereoView = myThJniEnv->GetMethodID(aJClass_Sharp, "setStereoView", "(Z)V"); postMessage("jp.co.sharp.android.stereo3dlcd !!!"); }*/ createApplication(); if(!myApp.isNull()) { if(!myApp->open()) { stError("Error: application can not be executed!"); } myApp->exec(); } else { stError("Error: no application to execute!"); } myApp.nullify(); // application is done but we are waiting for destroying event... bool isFirstWait = true; for(; !myToDestroy; ) { if(isFirstWait) { postExit(); isFirstWait = false; } StAndroidPollSource* aSource = NULL; int aNbEvents = 0; ALooper_pollAll(-1, NULL, &aNbEvents, (void** )&aSource); if(aSource != NULL) { aSource->process(this, aSource); } } freeSavedState(); pthread_mutex_lock(&myMutex); if(myInputQueue != NULL) { AInputQueue_detachLooper(myInputQueue); } AConfiguration_delete(myConfig); pthread_cond_broadcast(&myCond); pthread_mutex_unlock(&myMutex); myThJniEnv = NULL; StMessageBox::setCallback(NULL); THE_ANDROID_GLUE = NULL; myJavaVM->DetachCurrentThread(); }
static void* android_app_entry(void* param) { LOGV("+android_app_entry"); struct android_app* android_app = (struct android_app*)param; android_app->config = AConfiguration_new(); AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); print_cur_config(android_app); android_app->cmdPollSource.id = LOOPER_ID_MAIN; android_app->cmdPollSource.app = android_app; android_app->cmdPollSource.process = process_cmd; android_app->inputPollSource.id = LOOPER_ID_INPUT; android_app->inputPollSource.app = android_app; android_app->inputPollSource.process = process_input; ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, &android_app->cmdPollSource); android_app->looper = looper; pthread_mutex_lock(&android_app->mutex); android_app->running = 1; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); std::string sargv; // Load command line from ARGV parameter JNIEnv *env = GetEnvAttachThread(android_app->activity->vm); if(env) { jobject me = android_app->activity->clazz; jclass acl = env->GetObjectClass(me); //class pointer of NativeActivity jmethodID giid = env->GetMethodID(acl, "getIntent", "()Landroid/content/Intent;"); jobject intent = env->CallObjectMethod(me, giid); //Got our intent jclass icl = env->GetObjectClass(intent); //class pointer of Intent jmethodID gseid = env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); jstring jsARGV = (jstring)env->CallObjectMethod(intent, gseid, env->NewStringUTF("ARGV")); if(jsARGV) { const char *chARGV = env->GetStringUTFChars(jsARGV, 0); if(chARGV) { sargv = std::string(chARGV); LOGI("ARGV: pango %s", chARGV); } env->ReleaseStringUTFChars(jsARGV, chARGV); } android_app->activity->vm->DetachCurrentThread(); } // Set up argv/argc to pass to users main std::vector<std::string> vargv; vargv.push_back("pango"); // Parse parameters from ARGV android intent parameter std::istringstream iss(sargv); std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter<std::vector<std::string> >(vargv)); char* argv[vargv.size()+1]; for(size_t ac = 0; ac < vargv.size(); ++ac) { argv[ac] = new char[vargv[ac].size()]; strcpy( argv[ac], vargv[ac].c_str() ); } argv[vargv.size()] = NULL; // Call users standard main entry point. main(vargv.size(), argv); // Clean up parameters for(size_t ac = 0; ac < vargv.size(); ++ac) { delete[] argv[ac]; } android_app_destroy(android_app); LOGV("-android_app_entry"); return NULL; }