首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Runnables会阻塞UI线程吗?

Runnables会阻塞UI线程吗?
EN

Stack Overflow用户
提问于 2017-08-21 07:29:11
回答 4查看 5.7K关注 0票数 2

我试图了解UI线程的事件队列是如何工作的。我正在尝试运行一个代码,它可以被分解成许多部分,但不幸的是,它必须在UI线程上运行。因此,为了不阻塞UI线程并接收ANR,我想知道是否可以在许多Runnable对象中破解该代码并使用来自另一个线程的runOnUiThread运行它们。

我的问题是,这会阻止UI线程吗?例如,如果我有一段代码一定在5秒内运行,并且我将这段代码分解成1000个Runnable对象,并将它们添加到UI线程的事件队列中,那么它们之间的UI线程会处理其他事件吗?

编辑:,我想我找到了一种更好的方式来表达自己,以防上面的解释令人困惑。

  • 1000个Runnable对象只是一个例子,在实际代码中,我最多希望有10个。
  • 基本上,我想要10个Runnable对象,每个对象在UI线程上初始化一个Ad网络。我希望这些Runnable对象一个接一个地运行,而不是并行运行。另外,我希望UI线程能够在运行这些对象之间处理其他事件,这样我就不会得到一个ANR,以防运行所有10个run方法需要超过5秒。

注意:我不知道为什么必须在UI线程上初始化Ad网络,但它必须这样做,否则应用程序就会崩溃。它还在一些网络的sdks文档中声明,初始化必须在UI线程上进行。这就是为什么我需要在UI线程上一个接一个地运行它们,并且我不能在后台并行地运行它们。另外,该应用程序实际上是一个OpenGl游戏,因此对运行Runnable对象的调用将从GL线程进行,而不是主线程,因此它们将被添加到事件队列中,而不是立即执行。

EN

回答 4

Stack Overflow用户

发布于 2017-08-21 09:45:19

嗯,Runnable在您的runOnUiThread中只是在Main Thread中运行。

想象一下,一些简单的动作

代码语言:javascript
复制
textView.setText("example");

将阻塞主线程5毫秒。通常你不会看到它。

现在,假设您有大约1000个相同的操作,持续5秒。每隔一段Main Thread 5 ms。简单计算5ms * 1000 =5000 5ms=5秒。因此,它会永久性地阻止Main Thread。但如果你有10个操作,你只会阻塞50毫秒,换句话说,它只是1%的负荷,你不会感觉到。

因此,调用的可能数量取决于View的大小、渲染的难度和设备的速度。

对于精通AsyncTask的人来说,runOnUiThreadAsyncTask之间没有真正的区别,因为这1000 Runnables将以同样的方式在Main Thread中执行。

即使我在onCreate活动方法中做了同样的事情,也会很难阻止UI。

票数 1
EN

Stack Overflow用户

发布于 2017-08-21 13:24:02

是。在UI线程上执行的Runnable将阻塞主线程。

检查下面的方法是否对您有用。

  1. 使用活套从Main :requestHandler创建一个requestHandler
  2. 为主线程创建一个带活套的Handler:responseHandler和重写handleMessage方法
  3. post a Runnable任务在requestHandler
  4. Runnable任务中,调用responseHandler上的sendMessage
  5. 这个sendMessage结果在responseHandler中调用handleMessage
  6. Message获取属性并对其进行处理,更新UI

样本代码:

代码语言:javascript
复制
    /* 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

安卓-活套-处理程序-手链-i

票数 1
EN

Stack Overflow用户

发布于 2017-08-21 07:31:22

是的,如果你在Ui线程中运行大量的操作,你会感觉动画会停止或启动快门。这也取决于设备的速度。

我建议您将代码分为两部分。一个可以在后台完成,第二个需要Ui线程并在AsyncTask中执行它们。

使用doInBackgroud方法执行大量操作,使用onPostExecute更新UI。

注意:如果您将代码分解为1000个线程,并在一分钟内运行它们,那么可能会达到设备队列限制。(把它们分成10-50个部分。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45791504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档