Initialize Application object to avoid NPE

When an ApplicationInfo is set (commit
90293240cc), some devices (Nvidia Shield
TV) attempt to access the Application object, causing a
NullPointerException.

As a workaround, initialize an Application object.

Fixes <https://github.com/Genymobile/scrcpy/issues/940>
This commit is contained in:
Romain Vimont 2019-11-24 11:58:40 +01:00
parent ebdc2ee8b5
commit 2b845680b0

View file

@ -1,11 +1,15 @@
package com.genymobile.scrcpy; package com.genymobile.scrcpy;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Application;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.os.Looper; import android.os.Looper;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
public final class Workarounds { public final class Workarounds {
private Workarounds() { private Workarounds() {
@ -56,6 +60,17 @@ public final class Workarounds {
Field mBoundApplicationField = activityThreadClass.getDeclaredField("mBoundApplication"); Field mBoundApplicationField = activityThreadClass.getDeclaredField("mBoundApplication");
mBoundApplicationField.setAccessible(true); mBoundApplicationField.setAccessible(true);
mBoundApplicationField.set(activityThread, appBindData); mBoundApplicationField.set(activityThread, appBindData);
// Context ctx = activityThread.getSystemContext();
Method getSystemContextMethod = activityThreadClass.getDeclaredMethod("getSystemContext");
Context ctx = (Context) getSystemContextMethod.invoke(activityThread);
Application app = Instrumentation.newApplication(Application.class, ctx);
// activityThread.mInitialApplication = app;
Field mInitialApplicationField = activityThreadClass.getDeclaredField("mInitialApplication");
mInitialApplicationField.setAccessible(true);
mInitialApplicationField.set(activityThread, app);
} catch (Throwable throwable) { } catch (Throwable throwable) {
// this is a workaround, so failing is not an error // this is a workaround, so failing is not an error
Ln.w("Could not fill app info: " + throwable.getMessage()); Ln.w("Could not fill app info: " + throwable.getMessage());