我试图了解UI线程的事件队列是如何工作的。我正在尝试运行一个代码,它可以被分解成许多部分,但不幸的是,它必须在UI线程上运行。因此,为了不阻塞UI线程并接收ANR,我想知道是否可以在许多Runnable对象中破解该代码并使用来自另一个线程的runOnUiThread运行它们。
我的问题是,这会阻止UI线程吗?例如,如果我有一段代码一定在5秒内运行,并且我将这段代码分解成1000个Runnable对象,并将它们添加到UI线程的事件队列中,那么它们之间的UI线程会处理其他事件吗?
编辑:,我想我找到了一种更好的方式来表达自己,以防上面的解释令人困惑。
Runnable对象只是一个例子,在实际代码中,我最多希望有10个。Runnable对象,每个对象在UI线程上初始化一个Ad网络。我希望这些Runnable对象一个接一个地运行,而不是并行运行。另外,我希望UI线程能够在运行这些对象之间处理其他事件,这样我就不会得到一个ANR,以防运行所有10个run方法需要超过5秒。注意:我不知道为什么必须在UI线程上初始化Ad网络,但它必须这样做,否则应用程序就会崩溃。它还在一些网络的sdks文档中声明,初始化必须在UI线程上进行。这就是为什么我需要在UI线程上一个接一个地运行它们,并且我不能在后台并行地运行它们。另外,该应用程序实际上是一个OpenGl游戏,因此对运行Runnable对象的调用将从GL线程进行,而不是主线程,因此它们将被添加到事件队列中,而不是立即执行。
发布于 2017-08-21 09:45:19
嗯,Runnable在您的runOnUiThread中只是在Main Thread中运行。
想象一下,一些简单的动作
textView.setText("example");将阻塞主线程5毫秒。通常你不会看到它。
现在,假设您有大约1000个相同的操作,持续5秒。每隔一段Main Thread 5 ms。简单计算5ms * 1000 =5000 5ms=5秒。因此,它会永久性地阻止Main Thread。但如果你有10个操作,你只会阻塞50毫秒,换句话说,它只是1%的负荷,你不会感觉到。
因此,调用的可能数量取决于View的大小、渲染的难度和设备的速度。
对于精通AsyncTask的人来说,runOnUiThread和AsyncTask之间没有真正的区别,因为这1000 Runnables将以同样的方式在Main Thread中执行。
即使我在onCreate活动方法中做了同样的事情,也会很难阻止UI。
发布于 2017-08-21 13:24:02
是。在UI线程上执行的Runnable将阻塞主线程。
检查下面的方法是否对您有用。
requestHandler创建一个requestHandlerresponseHandler和重写handleMessage方法post a Runnable任务在requestHandler上Runnable任务中,调用responseHandler上的sendMessagesendMessage结果在responseHandler中调用handleMessage。Message获取属性并对其进行处理,更新UI样本代码:
/* 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);
}有用的文章:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
发布于 2017-08-21 07:31:22
是的,如果你在Ui线程中运行大量的操作,你会感觉动画会停止或启动快门。这也取决于设备的速度。
我建议您将代码分为两部分。一个可以在后台完成,第二个需要Ui线程并在AsyncTask中执行它们。
使用doInBackgroud方法执行大量操作,使用onPostExecute更新UI。
注意:如果您将代码分解为1000个线程,并在一分钟内运行它们,那么可能会达到设备队列限制。(把它们分成10-50个部分。)
https://stackoverflow.com/questions/45791504
复制相似问题