Fix meizu 16th NPE
Fill AppInfo to avoid NullPointerException on some devices. Fixes <https://github.com/Genymobile/scrcpy/issues/365> Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
parent
213c468c20
commit
90293240cc
2 changed files with 44 additions and 0 deletions
|
@ -53,6 +53,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
|
||||
public void streamScreen(Device device, FileDescriptor fd) throws IOException {
|
||||
Workarounds.prepareMainLooper();
|
||||
Workarounds.fillAppInfo();
|
||||
|
||||
MediaFormat format = createFormat(bitRate, maxFps, iFrameInterval);
|
||||
device.setRotationListener(this);
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package com.genymobile.scrcpy;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class Workarounds {
|
||||
private Workarounds() {
|
||||
// not instantiable
|
||||
|
@ -18,4 +23,42 @@ public final class Workarounds {
|
|||
// <https://github.com/Genymobile/scrcpy/issues/921>
|
||||
Looper.prepareMainLooper();
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateApi")
|
||||
public static void fillAppInfo() {
|
||||
try {
|
||||
// ActivityThread activityThread = new ActivityThread();
|
||||
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
|
||||
Constructor<?> activityThreadConstructor = activityThreadClass.getDeclaredConstructor();
|
||||
activityThreadConstructor.setAccessible(true);
|
||||
Object activityThread = activityThreadConstructor.newInstance();
|
||||
|
||||
// ActivityThread.sCurrentActivityThread = activityThread;
|
||||
Field sCurrentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
|
||||
sCurrentActivityThreadField.setAccessible(true);
|
||||
sCurrentActivityThreadField.set(null, activityThread);
|
||||
|
||||
// ActivityThread.AppBindData appBindData = new ActivityThread.AppBindData();
|
||||
Class<?> appBindDataClass = Class.forName("android.app.ActivityThread$AppBindData");
|
||||
Constructor<?> appBindDataConstructor = appBindDataClass.getDeclaredConstructor();
|
||||
appBindDataConstructor.setAccessible(true);
|
||||
Object appBindData = appBindDataConstructor.newInstance();
|
||||
|
||||
ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.packageName = "com.genymobile.scrcpy";
|
||||
|
||||
// appBindData.appInfo = applicationInfo;
|
||||
Field appInfo = appBindDataClass.getDeclaredField("appInfo");
|
||||
appInfo.setAccessible(true);
|
||||
appInfo.set(appBindData, applicationInfo);
|
||||
|
||||
// activityThread.mBoundApplication = appBindData;
|
||||
Field mBoundApplicationField = activityThreadClass.getDeclaredField("mBoundApplication");
|
||||
mBoundApplicationField.setAccessible(true);
|
||||
mBoundApplicationField.set(activityThread, appBindData);
|
||||
} catch (Throwable throwable) {
|
||||
// this is a workaround, so failing is not an error
|
||||
Ln.w("Could not fill app info: " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue