最有效的方式来持续更新Android中的UI线程

时间:2015-10-21 04:01:49

标签: java android multithreading android-asynctask

我正在通过创建秒表来试验Android开发中的线程。我目前有一个非常基本的执行,似乎在模拟器上运行得很好,但是在我的手机上运行时效率不高(相当新的Nexus 6,所以电话很好)。我的问题是,什么是连续更新UI线程的最有效方法,因为秒表需要做什么?

我目前正在AsyncTask中运行它,更新UI onProgressUpdate。我想AsyncTask不是最好的选择,但我也在我自己的Runnable中尝试过它,但是运行得更糟。我读过Handler类,但对如何使用它没有信心(或者知道它是否是答案)。下面是我创建和执行AsyncTask的地方,以及AsyncTask本身。我应该注意到这是片段。

var r1 = $.get("http://localhost:2000/api/group1");
var r2 = $.get("http://localhost:1000/api/group2");
var r3 = $.get("http://localhost:1000/api/group3");
var r4 = $.get("http://localhost:1000/api/group4");

$.when(r1, r2, r3, r4).done(function(a1, a2, a3, a4) {
  work(a1[0], a2[0], a3[0], a4[0]);

})

function work(group1, group2, group3, group4) {
  //This function will process all the data.
}

然后这是我的类,它扩展了AsyncTask

window -> devices (or shift-cmd-2) and there you'll see "View device log" button

-------更新---------

我很感激回应。我已经尝试了所有建议,但在真实设备上的性能仍然很糟糕。我在下面创建了一个简单的骨头示例。也许这个简单的骨头版本将帮助别人看到我正在做的是保持UI线程无法有效更新。它循环100,000次并使用处理程序尝试更新UI线程。谢谢!

// Where the thread kicks off on click
private class StartTimer implements View.OnClickListener{
    @Override
    public void onClick(View v) {
        // passes the stopWacth object and the view to update
        clockThread = new HiitClock(clockTv, stopWatch);
        clockThread.execute();
    }
}

2 个答案:

答案 0 :(得分:1)

您可以在更新视图的线程上发布runnable:

clock.post(new Runnable() {
    @Override public void run() {
        clock.setText(convertTime());
        // 50 millis to give the ui thread time to breath. Adjust according to your own experience
        clock.postDelayed(this, 50);
    }
});

(我省略了停止逻辑以保持示例简短。把它放回去是一个测试而不是重新发布runnable的问题。)

答案 1 :(得分:0)

您可以使用onProgressUpdate()来更新UI。除此之外,还有两种方法:

  1. 使用Activity的runOnUiThread方法:

      Activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //update your UI
                    }
                });
    
  2. 您也可以使用处理程序:

    Handler h = new Handler(){
      @Override
      public void handleMessage(Message msg){
         if(msg.what == 0){
            updateUI();
         }else{
            showErrorDialog();
         }
      }
    };