зеркало из https://github.com/mozilla/gecko-dev.git
Bug 889881 - Use IdleHandler to make MessageQueue.next() not block; r=blassey
This commit is contained in:
Родитель
e56ee2b07a
Коммит
ab6dffe101
|
@ -56,6 +56,7 @@ import android.net.ConnectivityManager;
|
|||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.MessageQueue;
|
||||
|
@ -293,6 +294,19 @@ public class GeckoAppShell
|
|||
}
|
||||
|
||||
public static void runGecko(String apkPath, String args, String url, String type) {
|
||||
// Preparation for pumpMessageLoop()
|
||||
MessageQueue.IdleHandler idleHandler = new MessageQueue.IdleHandler() {
|
||||
@Override public boolean queueIdle() {
|
||||
Handler geckoHandler = ThreadUtils.getGeckoHandler();
|
||||
Message idleMsg = Message.obtain(geckoHandler);
|
||||
// Use |Message.obj == GeckoHandler| to identify our "queue is empty" message
|
||||
idleMsg.obj = geckoHandler;
|
||||
geckoHandler.sendMessageAtFrontOfQueue(idleMsg);
|
||||
// Keep this IdleHandler
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Looper.myQueue().addIdleHandler(idleHandler);
|
||||
|
||||
// run gecko -- it will spawn its own thread
|
||||
GeckoAppShell.nativeInit();
|
||||
|
@ -321,6 +335,9 @@ public class GeckoAppShell
|
|||
|
||||
// and go
|
||||
GeckoLoader.nativeRun(combinedArgs);
|
||||
|
||||
// Remove pumpMessageLoop() idle handler
|
||||
Looper.myQueue().removeIdleHandler(idleHandler);
|
||||
}
|
||||
|
||||
// Called on the UI thread after Gecko loads.
|
||||
|
@ -2463,10 +2480,16 @@ public class GeckoAppShell
|
|||
}
|
||||
|
||||
public static boolean pumpMessageLoop() {
|
||||
Handler geckoHandler = ThreadUtils.getGeckoHandler();
|
||||
MessageQueue mq = Looper.myQueue();
|
||||
Message msg = getNextMessageFromQueue(mq);
|
||||
if (msg == null)
|
||||
return false;
|
||||
if (msg.getTarget() == geckoHandler && msg.obj == geckoHandler) {
|
||||
// Our "queue is empty" message; see runGecko()
|
||||
msg.recycle();
|
||||
return false;
|
||||
}
|
||||
if (msg.getTarget() == null)
|
||||
Looper.myLooper().quit();
|
||||
else
|
||||
|
|
|
@ -803,21 +803,14 @@ NS_EXPORT jobject JNICALL
|
|||
Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue(JNIEnv* jenv, jclass, jobject queue)
|
||||
{
|
||||
static jclass jMessageQueueCls = nullptr;
|
||||
static jfieldID jMessagesField;
|
||||
static jmethodID jNextMethod;
|
||||
if (!jMessageQueueCls) {
|
||||
jMessageQueueCls = (jclass) jenv->NewGlobalRef(jenv->FindClass("android/os/MessageQueue"));
|
||||
jMessagesField = jenv->GetFieldID(jMessageQueueCls, "mMessages", "Landroid/os/Message;");
|
||||
jNextMethod = jenv->GetMethodID(jMessageQueueCls, "next", "()Landroid/os/Message;");
|
||||
}
|
||||
if (!jMessageQueueCls || !jMessagesField || !jNextMethod)
|
||||
if (!jMessageQueueCls || !jNextMethod)
|
||||
return NULL;
|
||||
jobject msg = jenv->GetObjectField(queue, jMessagesField);
|
||||
// if queue.mMessages is null, queue.next() will block, which we don't want
|
||||
if (!msg)
|
||||
return msg;
|
||||
msg = jenv->CallObjectMethod(queue, jNextMethod);
|
||||
return msg;
|
||||
return jenv->CallObjectMethod(queue, jNextMethod);
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
|
|
Загрузка…
Ссылка в новой задаче