Perfect (almost) Qt on Android splash screen.

There is no need to show the splash image immediately when the
application starts, because it will be removed shortly in
QtActivityDelegate.java, therefore show the splash in
QtActivityDelegate.java.
This patch also adds a new option to AndroidManifest.xml which keeps
the splash screen visible until user to decides to hide it,
by using the QtAndroid::hideSplashScreen() function.

Change-Id: I8a29a5a757d626c4c9d6a2748a60ca3091ebf82d
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
BogDan Vatra 2016-02-15 19:19:58 +02:00
parent c05f2985eb
commit 3376e67abe
6 changed files with 52 additions and 26 deletions

View File

@ -48,6 +48,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Rect;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
@ -74,6 +75,7 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.PopupMenu;
import java.io.BufferedReader;
@ -127,6 +129,8 @@ public class QtActivityDelegate
private HashMap<Integer, QtSurface> m_surfaces = null;
private HashMap<Integer, View> m_nativeViews = null;
private QtLayout m_layout = null;
private ImageView m_splashScreen = null;
private boolean m_splashScreenSticky = false;
private QtEditText m_editText = null;
private InputMethodManager m_imm = null;
private boolean m_quitApp = true;
@ -873,6 +877,22 @@ public class QtActivityDelegate
};
}
m_layout = new QtLayout(m_activity, startApplication);
try {
ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA);
if (info.metaData.containsKey("android.app.splash_screen_drawable")) {
m_splashScreenSticky = info.metaData.containsKey("android.app.splash_screen_sticky") && info.metaData.getBoolean("android.app.splash_screen_sticky");
int id = info.metaData.getInt("android.app.splash_screen_drawable");
m_splashScreen = new ImageView(m_activity);
m_splashScreen.setImageDrawable(m_activity.getResources().getDrawable(id));
m_splashScreen.setScaleType(ImageView.ScaleType.FIT_XY);
m_splashScreen.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
m_layout.addView(m_splashScreen);
}
} catch (Exception e) {
e.printStackTrace();
}
m_editText = new QtEditText(m_activity, this);
m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE);
m_surfaces = new HashMap<Integer, QtSurface>();
@ -914,6 +934,15 @@ public class QtActivityDelegate
});
}
public void hideSplashScreen()
{
if (m_splashScreen == null)
return;
m_layout.removeView(m_splashScreen);
m_splashScreen = null;
}
public void initializeAccessibility()
{
new QtAccessibilityDelegate(m_activity, m_layout, this);
@ -937,22 +966,6 @@ public class QtActivityDelegate
e.printStackTrace();
}
// if splash screen is defined, then show it
// Note: QtActivity handles settting the splash screen
// in onCreate, change that too if you are changing
// how the splash screen should be displayed
try {
if (m_surfaces.size() == 0) {
ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA);
if (info.metaData.containsKey("android.app.splash_screen_drawable"))
m_activity.getWindow().setBackgroundDrawableResource(info.metaData.getInt("android.app.splash_screen_drawable"));
else
m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000));
}
} catch (Exception e) {
e.printStackTrace();
}
int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
if (rotation != m_currentRotation) {
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
@ -1274,6 +1287,8 @@ public class QtActivityDelegate
m_layout.addView(surface, surfaceCount);
m_surfaces.put(id, surface);
if (!m_splashScreenSticky)
hideSplashScreen();
}
public void setSurfaceGeometry(int id, int x, int y, int w, int h) {

View File

@ -728,6 +728,17 @@ public class QtNative
});
}
private static void hideSplashScreen()
{
runAction(new Runnable() {
@Override
public void run() {
if (m_activityDelegate != null)
m_activityDelegate.hideSplashScreen();
}
});
}
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels,
int screenHeightPixels,

View File

@ -166,15 +166,6 @@ public class QtActivityLoader extends QtLoader {
+ "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t";
if (null == m_activity.getLastNonConfigurationInstance()) {
// if splash screen is defined, then show it
// Note: QtActivityDelegate handles updating the splash screen
// in onConfigurationChanged, change that too if you are changing
// how the splash screen should be displayed
if (m_contextInfo.metaData.containsKey("android.app.splash_screen_drawable"))
m_activity.getWindow().setBackgroundDrawableResource(m_contextInfo.metaData.getInt("android.app.splash_screen_drawable"));
else
m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000));
if (m_contextInfo.metaData.containsKey("android.app.background_running")
&& m_contextInfo.metaData.getBoolean("android.app.background_running")) {
ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=0\t";

View File

@ -38,6 +38,7 @@
<!-- Splash screen -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen -->
<!-- Background running -->

View File

@ -56,6 +56,7 @@ static jobject g_jClassLoader = Q_NULLPTR;
static jint g_androidSdkVersion = 0;
static jclass g_jNativeClass = Q_NULLPTR;
static jmethodID g_runPendingCppRunnablesMethodID = Q_NULLPTR;
static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR;
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex);
@ -338,7 +339,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
"runPendingCppRunnablesOnUiThread",
"()V");
g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "()V");
g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative));
env->DeleteLocalRef(jQtNative);
@ -424,4 +425,9 @@ void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventList
g_keyEventListeners()->listeners.removeOne(listener);
}
void QtAndroidPrivate::hideSplashScreen(JNIEnv *env)
{
env->CallStaticVoidMethod(g_jNativeClass, g_hideSplashScreenMethodID);
}
QT_END_NAMESPACE

View File

@ -127,6 +127,8 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener);
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
Q_CORE_EXPORT void hideSplashScreen(JNIEnv *env);
}
QT_END_NAMESPACE