Android: Fix crash at exit

Delay the exit call until Java part finishes the execution.
We must be sure all the threads are stopped (hanged), when we
call exit, otherwise java thread will try to use static vars
that are freed by the qt thread.

We also need to call exit from Qt thread, otherwise Qt will complain
about it.

Change-Id: Ia1e7a4d7d56c39d38313f040aab618ec5a68dfb6
Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
This commit is contained in:
BogDan Vatra 2015-12-17 09:30:16 +02:00
parent 08ee579cf0
commit 0b10d41c3d
3 changed files with 25 additions and 3 deletions

View File

@ -919,6 +919,7 @@ public class QtActivityDelegate
public void onDestroy()
{
if (m_quitApp) {
QtNative.terminateQt();
if (m_debuggerProcess != null)
m_debuggerProcess.destroy();
System.exit(0);// FIXME remove it or find a better way

View File

@ -294,7 +294,12 @@ public class QtNative
private static void quitApp()
{
m_activity.finish();
runAction(new Runnable() {
@Override
public void run() {
m_activity.finish();
}
});
}
//@ANDROID-9

View File

@ -34,6 +34,7 @@
#include <dlfcn.h>
#include <pthread.h>
#include <semaphore.h>
#include <qplugin.h>
#include <qdebug.h>
@ -91,6 +92,8 @@ extern "C" typedef int (*Main)(int, char **); //use the standard main method to
static Main m_main = nullptr;
static void *m_mainLibraryHnd = nullptr;
static QList<QByteArray> m_applicationParams;
pthread_t m_qtAppThread = 0;
static sem_t m_exitSemaphore, m_terminateSemaphore;
struct SurfaceData
{
@ -454,6 +457,10 @@ static void *startMainMethod(void */*data*/)
if (vm != 0)
vm->DetachCurrentThread();
sem_post(&m_terminateSemaphore);
sem_wait(&m_exitSemaphore);
sem_destroy(&m_exitSemaphore);
// We must call exit() to ensure that all global objects will be destructed
exit(ret);
return 0;
@ -503,8 +510,13 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
return false;
}
pthread_t appThread;
return pthread_create(&appThread, nullptr, startMainMethod, nullptr) == 0;
if (sem_init(&m_exitSemaphore, 0, 0) == -1)
return false;
if (sem_init(&m_terminateSemaphore, 0, 0) == -1)
return false;
return pthread_create(&m_qtAppThread, nullptr, startMainMethod, nullptr) == 0;
}
@ -518,6 +530,8 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
static void terminateQt(JNIEnv *env, jclass /*clazz*/)
{
sem_wait(&m_terminateSemaphore);
sem_destroy(&m_terminateSemaphore);
env->DeleteGlobalRef(m_applicationClass);
env->DeleteGlobalRef(m_classLoaderObject);
if (m_resourcesObj)
@ -535,6 +549,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
m_androidPlatformIntegration = nullptr;
delete m_androidAssetsFileEngineHandler;
m_androidAssetsFileEngineHandler = nullptr;
sem_post(&m_exitSemaphore);
pthread_join(m_qtAppThread, nullptr);
}
static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)