mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-09 17:49:03 +00:00
Run a main looper
Instead of blocking the main thread until completion, run a looper. This will allow the main thread to process any event posted to the main looper. Refs #6009 comment <https://github.com/Genymobile/scrcpy/pull/6009#issuecomment-2940810736> PR #6129 <https://github.com/Genymobile/scrcpy/pull/6129>
This commit is contained in:
parent
ca4f50c5ef
commit
283326b2f6
2 changed files with 19 additions and 27 deletions
|
@ -25,9 +25,11 @@ import com.genymobile.scrcpy.video.SurfaceEncoder;
|
||||||
import com.genymobile.scrcpy.video.VideoSource;
|
import com.genymobile.scrcpy.video.VideoSource;
|
||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -55,17 +57,7 @@ public final class Server {
|
||||||
this.fatalError = true;
|
this.fatalError = true;
|
||||||
}
|
}
|
||||||
if (running == 0 || this.fatalError) {
|
if (running == 0 || this.fatalError) {
|
||||||
notify();
|
Looper.getMainLooper().quitSafely();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized void await() {
|
|
||||||
try {
|
|
||||||
while (running > 0 && !fatalError) {
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +96,7 @@ public final class Server {
|
||||||
boolean audio = options.getAudio();
|
boolean audio = options.getAudio();
|
||||||
boolean sendDummyByte = options.getSendDummyByte();
|
boolean sendDummyByte = options.getSendDummyByte();
|
||||||
|
|
||||||
|
prepareMainLooper();
|
||||||
Workarounds.apply();
|
Workarounds.apply();
|
||||||
|
|
||||||
List<AsyncProcessor> asyncProcessors = new ArrayList<>();
|
List<AsyncProcessor> asyncProcessors = new ArrayList<>();
|
||||||
|
@ -172,7 +165,7 @@ public final class Server {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
completion.await();
|
Looper.loop(); // interrupted by the Completion implementation
|
||||||
} finally {
|
} finally {
|
||||||
if (cleanUp != null) {
|
if (cleanUp != null) {
|
||||||
cleanUp.interrupt();
|
cleanUp.interrupt();
|
||||||
|
@ -201,6 +194,20 @@ public final class Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void prepareMainLooper() {
|
||||||
|
// Like Looper.prepareMainLooper(), but with quitAllowed set to true
|
||||||
|
Looper.prepare();
|
||||||
|
synchronized (Looper.class) {
|
||||||
|
try {
|
||||||
|
Field field = Looper.class.getDeclaredField("sMainLooper");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(null, Looper.myLooper());
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
int status = 0;
|
int status = 0;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -29,8 +29,6 @@ public final class Workarounds {
|
||||||
private static final Object ACTIVITY_THREAD;
|
private static final Object ACTIVITY_THREAD;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
prepareMainLooper();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// ActivityThread activityThread = new ActivityThread();
|
// ActivityThread activityThread = new ActivityThread();
|
||||||
ACTIVITY_THREAD_CLASS = Class.forName("android.app.ActivityThread");
|
ACTIVITY_THREAD_CLASS = Class.forName("android.app.ActivityThread");
|
||||||
|
@ -77,19 +75,6 @@ public final class Workarounds {
|
||||||
fillAppContext();
|
fillAppContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private static void prepareMainLooper() {
|
|
||||||
// Some devices internally create a Handler when creating an input Surface, causing an exception:
|
|
||||||
// "Can't create handler inside thread that has not called Looper.prepare()"
|
|
||||||
// <https://github.com/Genymobile/scrcpy/issues/240>
|
|
||||||
//
|
|
||||||
// Use Looper.prepareMainLooper() instead of Looper.prepare() to avoid a NullPointerException:
|
|
||||||
// "Attempt to read from field 'android.os.MessageQueue android.os.Looper.mQueue'
|
|
||||||
// on a null object reference"
|
|
||||||
// <https://github.com/Genymobile/scrcpy/issues/921>
|
|
||||||
Looper.prepareMainLooper();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fillAppInfo() {
|
private static void fillAppInfo() {
|
||||||
try {
|
try {
|
||||||
// ActivityThread.AppBindData appBindData = new ActivityThread.AppBindData();
|
// ActivityThread.AppBindData appBindData = new ActivityThread.AppBindData();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue