summaryrefslogtreecommitdiffstats
path: root/src/android/jar/src/org/qtproject/qt5/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/jar/src/org/qtproject/qt5/android')
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java4
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java134
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java4
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtThread.java112
4 files changed, 201 insertions, 53 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 0e28b964e8..6b8577116e 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -921,6 +921,7 @@ public class QtActivityDelegate
public void onTerminate()
{
QtNative.terminateQt();
+ QtNative.m_qtThread.exit();
}
public void onCreate(Bundle savedInstanceState)
@@ -1076,7 +1077,8 @@ public class QtActivityDelegate
QtNative.setActivity(null, null);
if (m_debuggerProcess != null)
m_debuggerProcess.destroy();
- System.exit(0);// FIXME remove it or find a better way
+ QtNative.m_qtThread.exit();
+ System.exit(0);
}
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 1cf3bca5f7..3db3453263 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -98,6 +98,7 @@ public class QtNative
private static ClipboardManager m_clipboardManager = null;
private static Method m_checkSelfPermissionMethod = null;
private static Boolean m_tabletEventSupported = null;
+ public static QtThread m_qtThread = new QtThread();
private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
@Override
public void run() {
@@ -164,55 +165,64 @@ public class QtNative
}
// this method loads full path libs
- public static void loadQtLibraries(ArrayList<String> libraries)
+ public static void loadQtLibraries(final ArrayList<String> libraries)
{
- if (libraries == null)
- return;
-
- for (String libName : libraries) {
- try {
- File f = new File(libName);
- if (f.exists())
- System.load(libName);
- } catch (SecurityException e) {
- Log.i(QtTAG, "Can't load '" + libName + "'", e);
- } catch (Exception e) {
- Log.i(QtTAG, "Can't load '" + libName + "'", e);
+ m_qtThread.run(new Runnable() {
+ @Override
+ public void run() {
+ if (libraries == null)
+ return;
+ for (String libName : libraries) {
+ try {
+ File f = new File(libName);
+ if (f.exists())
+ System.load(libName);
+ } catch (SecurityException e) {
+ Log.i(QtTAG, "Can't load '" + libName + "'", e);
+ } catch (Exception e) {
+ Log.i(QtTAG, "Can't load '" + libName + "'", e);
+ }
+ }
}
- }
+ });
}
// this method loads bundled libs by name.
- public static void loadBundledLibraries(ArrayList<String> libraries, String nativeLibraryDir)
+ public static void loadBundledLibraries(final ArrayList<String> libraries, final String nativeLibraryDir)
{
- if (libraries == null)
- return;
+ m_qtThread.run(new Runnable() {
+ @Override
+ public void run() {
+ if (libraries == null)
+ return;
- for (String libName : libraries) {
- try {
- String libNameTemplate = "lib" + libName + ".so";
- File f = new File(nativeLibraryDir + libNameTemplate);
- if (!f.exists()) {
- Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
+ for (String libName : libraries) {
try {
- ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(),
- PackageManager.GET_META_DATA);
- String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir;
- if (info.metaData.containsKey("android.app.system_libs_prefix"))
- systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix");
- f = new File(systemLibraryDir + libNameTemplate);
- } catch (Exception e) {
+ String libNameTemplate = "lib" + libName + ".so";
+ File f = new File(nativeLibraryDir + libNameTemplate);
+ if (!f.exists()) {
+ Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
+ try {
+ ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(),
+ PackageManager.GET_META_DATA);
+ String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir;
+ if (info.metaData.containsKey("android.app.system_libs_prefix"))
+ systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix");
+ f = new File(systemLibraryDir + libNameTemplate);
+ } catch (Exception e) {
+ }
+ }
+ if (f.exists())
+ System.load(f.getAbsolutePath());
+ else
+ Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
+ } catch (Exception e) {
+ Log.i(QtTAG, "Can't load '" + libName + "'", e);
}
}
- if (f.exists())
- System.load(f.getAbsolutePath());
- else
- Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
- } catch (Exception e) {
- Log.i(QtTAG, "Can't load '" + libName + "'", e);
}
- }
+ });
}
public static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate)
@@ -293,7 +303,7 @@ public class QtNative
}
public static boolean startApplication(String params,
- String environment,
+ final String environment,
String mainLibrary,
String nativeLibraryDir) throws Exception
{
@@ -317,23 +327,42 @@ public class QtNative
if (params == null)
params = "-platform\tandroid";
- boolean res = false;
+ final String mainLibraryPath = f.getAbsolutePath();
+ final boolean[] res = new boolean[1];
+ res[0] = false;
synchronized (m_mainActivityMutex) {
- res = startQtAndroidPlugin();
- setDisplayMetrics(m_displayMetricsScreenWidthPixels,
- m_displayMetricsScreenHeightPixels,
- m_displayMetricsDesktopWidthPixels,
- m_displayMetricsDesktopHeightPixels,
- m_displayMetricsXDpi,
- m_displayMetricsYDpi,
- m_displayMetricsScaledDensity,
- m_displayMetricsDensity);
if (params.length() > 0 && !params.startsWith("\t"))
params = "\t" + params;
- startQtApplication(f.getAbsolutePath() + params, environment);
+ final String qtParams = f.getAbsolutePath() + params;
+ m_qtThread.run(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ System.load(mainLibraryPath);
+ } catch (Exception e) {
+ Log.i(QtTAG, "Can't load '" + mainLibraryPath + "'", e);
+ }
+ res[0] = startQtAndroidPlugin(qtParams, environment);
+ setDisplayMetrics(m_displayMetricsScreenWidthPixels,
+ m_displayMetricsScreenHeightPixels,
+ m_displayMetricsDesktopWidthPixels,
+ m_displayMetricsDesktopHeightPixels,
+ m_displayMetricsXDpi,
+ m_displayMetricsYDpi,
+ m_displayMetricsScaledDensity,
+ m_displayMetricsDensity);
+ }
+ });
+ m_qtThread.post(new Runnable() {
+ @Override
+ public void run() {
+ startQtApplication();
+ }
+ });
+ waitForServiceSetup();
m_started = true;
}
- return res;
+ return res[0];
}
public static void setApplicationDisplayMetrics(int screenWidthPixels,
@@ -377,8 +406,9 @@ public class QtNative
// application methods
- public static native void startQtApplication(String params, String env);
- public static native boolean startQtAndroidPlugin();
+ public static native boolean startQtAndroidPlugin(String params, String env);
+ public static native void startQtApplication();
+ public static native void waitForServiceSetup();
public static native void quitQtCoreApplication();
public static native void quitQtAndroidPlugin();
public static native void terminateQt();
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java
index 195ec376c9..ae06fa6268 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java
@@ -187,6 +187,10 @@ public class QtServiceDelegate
public void onDestroy()
{
QtNative.quitQtCoreApplication();
+ QtNative.terminateQt();
+ QtNative.setService(null, null);
+ QtNative.m_qtThread.exit();
+ System.exit(0);
}
public IBinder onBind(Intent intent)
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtThread.java b/src/android/jar/src/org/qtproject/qt5/android/QtThread.java
new file mode 100644
index 0000000000..975e787345
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtThread.java
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 BogDan Vatra <bogdan@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android;
+
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+public class QtThread {
+ private ArrayList<Runnable> m_pendingRunnables = new ArrayList<Runnable>();
+ private boolean m_exit = false;
+ private Thread m_qtThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (!m_exit) {
+ try {
+ ArrayList<Runnable> pendingRunnables;
+ synchronized (m_qtThread) {
+ if (m_pendingRunnables.size() == 0)
+ m_qtThread.wait();
+ pendingRunnables = new ArrayList<Runnable>(m_pendingRunnables);
+ m_pendingRunnables.clear();
+ }
+ for (Runnable runnable : pendingRunnables)
+ runnable.run();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+
+ QtThread() {
+ m_qtThread.setName("qtMainLoopThread");
+ m_qtThread.start();
+ }
+
+ public void post(final Runnable runnable) {
+ synchronized (m_qtThread) {
+ m_pendingRunnables.add(runnable);
+ m_qtThread.notify();
+ }
+ }
+
+ public void run(final Runnable runnable) {
+ final Semaphore sem = new Semaphore(0);
+ synchronized (m_qtThread) {
+ m_pendingRunnables.add(new Runnable() {
+ @Override
+ public void run() {
+ runnable.run();
+ sem.release();
+ }
+ });
+ m_qtThread.notify();
+ }
+ try {
+ sem.acquire();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void exit()
+ {
+ m_exit = true;
+ synchronized (m_qtThread) {
+ m_qtThread.notify();
+ }
+ try {
+ m_qtThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}