我试图了解UI线程的事件队列是如何工作的。我试图运行可以分解成许多部分的代码但不幸的是它必须在UI线程上运行。因此,为了不阻止UI线程并接收ANR,我想知道我是否可以在许多Runnable
个对象中破坏该代码并使用另一个线程中的runOnUiThread
运行它们。
我的问题是,这会阻止UI线程吗?例如,如果我有一段代码肯定会在5秒内运行并且我将这些代码分解为,那么让我们说1000 Runnable
个对象,并将它们添加到UI线程的事件队列中,其他事件是否会被它们之间的UI线程处理?
编辑:我认为如果上述解释令人困惑,我发现了一种更好的表达方式。
Runnable
个对象只是一个例子,在我想要的实际代码中最多只有10个。Runnable
个对象,每个对象在UI线程上初始化一个广告网络。我希望这些Runnable
对象一个接一个地运行,而不是并行运行。此外,我希望UI线程能够在运行这些对象之间处理其他事件,以便在运行所有10个run
方法时,我不会获得ANR超过5秒。 注意:我不知道为什么必须在UI线程上初始化广告网络,但它必须,否则应用程序崩溃。它还说明了一些网络'的SDK'初始化必须在UI线程上发生的文档。这就是为什么我需要在UI线程上一个接一个地运行它们,我不能在后台并行运行它们。
此外,该应用程序实际上是一个OpenGl游戏,因此运行Runnable
对象的调用将来自GL线程,而不是主线程,因此它们将被添加到事件队列中,而不是立即执行。 / p>
答案 0 :(得分:1)
嗯,Runnable
中的runOnUiThread
只是Main Thread
中的操作。
想象一下像
这样的简单动作textView.setText("example");
将阻止主线程持续5 ms。通常你不会看到它。
现在假设你有5次相同的1000次操作。每个块Main Thread
持续5毫秒。简单计算5ms * 1000 = 5000ms = 5秒。所以它会永久阻止Main Thread
。但是如果你有10个操作,你将只阻止50毫秒,换句话说它只有1%的负载,你感觉不到。
所以可能的调用量取决于View
的大小,渲染的难度以及设备的速度。
P.S。对于AsyncTask
的专家 - runOnUiThread
和AsyncTask
之间没有真正区别,因为那些Runnables
将以同样的方式在Main Thread
中执行。
即使我在Activity的创建方法中做同样的事情也会阻止UI
答案 1 :(得分:1)
是。在UI线程上执行的Runnable
将阻止主线程。
检查以下方法是否对您有用。
requestHandler
responseHandler
并覆盖handleMessage
方法post
Runnable
上的requestHandler
任务
Runnable
内部任务,请致电sendMessage
responseHandler
sendMessage
handleMessage
responseHandler
Message
次 /* Handler */
Handler requestHandler = new Handler(Looper.getMainLooper());
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Adwork task is completed:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
for ( int i=0; i<10; i++) {
// Start Adwork task
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
/* Your business logic goes here */
// Send some result after computation
String text = "" + (++rId);
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
System.out.println(text.toString());
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
}
次结果调用。{/ 1}
flatMap
获取属性并对其进行处理,更新用户界面示例代码:
tl
.flatMap { p =>
p.from -> (p.amount, 0),
p.to -> (0, p.amount)
}.groupBy(_._1)
.mapValues { tuples =>
tuples.foldLeft((0,0)) { case ((a,b), (_, (c,d))) => (a+c, b+d) }
}
有用的文章:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
答案 2 :(得分:0)
是的,如果你在Ui线程中运行大量操作,你会觉得动画会停止或启动快门。它还取决于设备的速度。
我建议你将代码分为两部分。一个可以在后台完成,另一个需要Ui线程并在AsyncTask中执行它们。
使用doInBackgroud
方法执行繁重操作,使用onPostExecute
更新UI。
注意:如果您将代码分成1000个线程并在一瞬间运行它们,那么您可能会遇到设备队列限制。 (将它们分成10-50个部分。)
答案 3 :(得分:0)
您要找的是AsyncTask。
这些设计用于执行一些后台处理,而UI线程继续。它不会阻止UI,也不会导致ANR。
在AsyncTask中,是一种onPostExecute
方法,允许您将结果发布回UI。所以它并没有完全脱离UI线程。在后台处理期间连接onProgressUpdate