mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-09 09:39:17 +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 android.os.Build;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -55,17 +57,7 @@ public final class Server {
|
|||
this.fatalError = true;
|
||||
}
|
||||
if (running == 0 || this.fatalError) {
|
||||
notify();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void await() {
|
||||
try {
|
||||
while (running > 0 && !fatalError) {
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
Looper.getMainLooper().quitSafely();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +96,7 @@ public final class Server {
|
|||
boolean audio = options.getAudio();
|
||||
boolean sendDummyByte = options.getSendDummyByte();
|
||||
|
||||
prepareMainLooper();
|
||||
Workarounds.apply();
|
||||
|
||||
List<AsyncProcessor> asyncProcessors = new ArrayList<>();
|
||||
|
@ -172,7 +165,7 @@ public final class Server {
|
|||
});
|
||||
}
|
||||
|
||||
completion.await();
|
||||
Looper.loop(); // interrupted by the Completion implementation
|
||||
} finally {
|
||||
if (cleanUp != null) {
|
||||
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) {
|
||||
int status = 0;
|
||||
try {
|
||||
|
|
|
@ -29,8 +29,6 @@ public final class Workarounds {
|
|||
private static final Object ACTIVITY_THREAD;
|
||||
|
||||
static {
|
||||
prepareMainLooper();
|
||||
|
||||
try {
|
||||
// ActivityThread activityThread = new ActivityThread();
|
||||
ACTIVITY_THREAD_CLASS = Class.forName("android.app.ActivityThread");
|
||||
|
@ -77,19 +75,6 @@ public final class Workarounds {
|
|||
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() {
|
||||
try {
|
||||
// ActivityThread.AppBindData appBindData = new ActivityThread.AppBindData();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue