Android: use WeakReference for static activity/service objects
Wrap the activity and service static objects with a WeakReference to fix a potential memory leak warning. Task-number: QTBUG-118077 Change-Id: Ifafd137cc49ec5ea23d8425b6bd58b43573970b9 Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
f6e5e52c84
commit
9d3b55b2a8
@ -6,6 +6,7 @@ package org.qtproject.qt.android;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.WindowMetrics;
|
import android.view.WindowMetrics;
|
||||||
import android.view.inputmethod.BaseInputConnection;
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
import android.view.inputmethod.CompletionInfo;
|
import android.view.inputmethod.CompletionInfo;
|
||||||
@ -61,6 +62,8 @@ public class QtInputConnection extends BaseInputConnection
|
|||||||
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
|
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
|
||||||
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
|
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
|
||||||
|
|
||||||
|
private static final String QtTAG = "QtInputConnection";
|
||||||
|
|
||||||
private final QtInputConnectionListener m_qtInputConnectionListener;
|
private final QtInputConnectionListener m_qtInputConnectionListener;
|
||||||
|
|
||||||
class HideKeyboardRunnable implements Runnable {
|
class HideKeyboardRunnable implements Runnable {
|
||||||
@ -68,6 +71,11 @@ public class QtInputConnection extends BaseInputConnection
|
|||||||
public void run() {
|
public void run() {
|
||||||
// Check that the keyboard is really no longer there.
|
// Check that the keyboard is really no longer there.
|
||||||
Activity activity = QtNative.activity();
|
Activity activity = QtNative.activity();
|
||||||
|
if (activity == null) {
|
||||||
|
Log.w(QtTAG, "HideKeyboardRunnable: The activity reference is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Rect r = new Rect();
|
Rect r = new Rect();
|
||||||
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import android.view.ContextMenu;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -31,9 +32,9 @@ import javax.net.ssl.X509TrustManager;
|
|||||||
|
|
||||||
public class QtNative
|
public class QtNative
|
||||||
{
|
{
|
||||||
private static Activity m_activity = null;
|
private static WeakReference<Activity> m_activity = null;
|
||||||
private static boolean m_activityPaused = false;
|
private static boolean m_activityPaused = false;
|
||||||
private static Service m_service = null;
|
private static WeakReference<Service> m_service = null;
|
||||||
public static final Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations
|
public static final Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations
|
||||||
|
|
||||||
public static final String QtTAG = "Qt JAVA";
|
public static final String QtTAG = "Qt JAVA";
|
||||||
@ -54,9 +55,7 @@ public class QtNative
|
|||||||
|
|
||||||
public static boolean isStarted()
|
public static boolean isStarted()
|
||||||
{
|
{
|
||||||
boolean hasActivity = m_activity != null;
|
return m_started && (isActivityValid() || isServiceValid());
|
||||||
boolean hasService = m_service != null;
|
|
||||||
return m_started && (hasActivity || hasService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
@UsedFromNativeCode
|
||||||
@ -73,14 +72,14 @@ public class QtNative
|
|||||||
public static void setActivity(Activity qtMainActivity)
|
public static void setActivity(Activity qtMainActivity)
|
||||||
{
|
{
|
||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
m_activity = qtMainActivity;
|
m_activity = new WeakReference<>(qtMainActivity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setService(Service qtMainService)
|
public static void setService(Service qtMainService)
|
||||||
{
|
{
|
||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
m_service = qtMainService;
|
m_service = new WeakReference<>(qtMainService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,23 +87,33 @@ public class QtNative
|
|||||||
public static Activity activity()
|
public static Activity activity()
|
||||||
{
|
{
|
||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
return m_activity;
|
return m_activity != null ? m_activity.get() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isActivityValid()
|
||||||
|
{
|
||||||
|
return m_activity != null && m_activity.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
@UsedFromNativeCode
|
||||||
public static Service service()
|
public static Service service()
|
||||||
{
|
{
|
||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
return m_service;
|
return m_service != null ? m_service.get() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isServiceValid()
|
||||||
|
{
|
||||||
|
return m_service != null && m_service.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
@UsedFromNativeCode
|
||||||
public static Context getContext() {
|
public static Context getContext() {
|
||||||
if (m_activity != null)
|
if (isActivityValid())
|
||||||
return m_activity;
|
return m_activity.get();
|
||||||
return m_service;
|
return service();
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
@UsedFromNativeCode
|
||||||
@ -174,7 +183,13 @@ public class QtNative
|
|||||||
if (!mime.isEmpty())
|
if (!mime.isEmpty())
|
||||||
intent.setDataAndType(uri, mime);
|
intent.setDataAndType(uri, mime);
|
||||||
|
|
||||||
activity().startActivity(intent);
|
Activity activity = activity();
|
||||||
|
if (activity == null) {
|
||||||
|
Log.w(QtTAG, "openURL(): The activity reference is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
activity.startActivity(intent);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -209,7 +224,7 @@ public class QtNative
|
|||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
final Looper mainLooper = Looper.getMainLooper();
|
final Looper mainLooper = Looper.getMainLooper();
|
||||||
final Handler handler = new Handler(mainLooper);
|
final Handler handler = new Handler(mainLooper);
|
||||||
final boolean active = (m_activity != null && !m_activityPaused) || m_service != null;
|
final boolean active = (isActivityValid() && !m_activityPaused) || isServiceValid();
|
||||||
if (!active || !handler.post(action))
|
if (!active || !handler.post(action))
|
||||||
m_lostActions.add(action);
|
m_lostActions.add(action);
|
||||||
}
|
}
|
||||||
@ -219,9 +234,9 @@ public class QtNative
|
|||||||
private static void runPendingCppRunnablesOnAndroidThread()
|
private static void runPendingCppRunnablesOnAndroidThread()
|
||||||
{
|
{
|
||||||
synchronized (m_mainActivityMutex) {
|
synchronized (m_mainActivityMutex) {
|
||||||
if (m_activity != null) {
|
if (isActivityValid()) {
|
||||||
if (!m_activityPaused)
|
if (!m_activityPaused)
|
||||||
m_activity.runOnUiThread(runPendingCppRunnablesRunnable);
|
m_activity.get().runOnUiThread(runPendingCppRunnablesRunnable);
|
||||||
else
|
else
|
||||||
runAction(runPendingCppRunnablesRunnable);
|
runAction(runPendingCppRunnablesRunnable);
|
||||||
} else {
|
} else {
|
||||||
@ -278,10 +293,10 @@ public class QtNative
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
quitQtAndroidPlugin();
|
quitQtAndroidPlugin();
|
||||||
if (m_activity != null)
|
if (isActivityValid())
|
||||||
m_activity.finish();
|
m_activity.get().finish();
|
||||||
if (m_service != null)
|
if (isServiceValid())
|
||||||
m_service.stopSelf();
|
m_service.get().stopSelf();
|
||||||
|
|
||||||
m_started = false;
|
m_started = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user