在asynctask中每x次更新标记位置

时间:2018-12-09 16:38:48

标签: java android android-asynctask

我想模拟标记在地图上的位置。我在ArrayList中存储了LatLng值的列表。我使用此值每秒更新一次地图。我需要此函数才能在AsyncTask中工作,以便我的UI线程仍然可以响应。

最初,我尝试使用Thread.sleep(),但使应用程序没有响应。

protected String doInBackground(Void... voids) {
    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < waypoint.size(); i++) {
                marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
                marker.setPosition(waypoint.get(i));
                try {
                    Thread.sleep(1000); // Thread sleep made application not responsive.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }, 500);
    return null;
}

我也尝试使用.postDelayed,但是整数i需要声明为final,这是一个问题,因为我需要整数来更改值。

protected String doInBackground(Void... voids) {
    for (int i = 0; i < waypoint.size(); i++) {
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
                marker.setPosition(waypoint.get(i)); // Integer i needs to declare final.
            }
        }, 1000);
    }
    return null;
}

有没有办法做到这一点?谢谢。

3 个答案:

答案 0 :(得分:0)

如果您可以保留工作线程,则Thread.sleep()方法是可以的。代码中的问题是您正在暂停的线程是UI线程,这就是您的应用程序冻结的原因。您必须了解,您所做的只是使用Handler构造将可运行对象发布到UI线程,仅此而已。

在第二种方法中,可以在基于AsyncTask的类中重写publishProgress(在UI线程中提供)后,转储Handler部分并使用onProgressUpdate(从后台调用)。它的作用相同,但样板更少。看看https://developer.android.com/reference/android/os/AsyncTask了解详情。

最后,为了规避匿名类中的最终要求,可以声明一个元素的最终数组,并使用位置0读取/写入值。希望您不需要经常这样做。

答案 1 :(得分:0)

最快的方法(但在使用多线程时不是最正确的方法)是:

protected String doInBackground(Void... voids) {
for (final TYPE_OF_WAYPOINT cWaypoint : waypoint) {
    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
            marker.setPosition(cWaypoint);
        }
    }, 1000);
}
return null;

}

我不知道“路标”列表的类型是什么,所以我写了“ TYPE_OF_WAYPOINTS”作为占位符。

答案 2 :(得分:0)

@emandt的答案无效,但他给出的想法可能有效。因此,我尝试了一下,对他的答案进行了一些修改,使它工作正常:

protected String doInBackground(Void... voids) {
for (final TYPE_OF_WAYPOINT cWaypoint : waypoint) {
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            marker = googleMap.addMarker(new MarkerOptions().position(waypoint.get(0)));
            marker.setPosition(cWaypoint);
        }
    });
    try {
        Thread.sleep(1000);
    } catch (Exception e) {
        // catch exception here
    }
}
return null;
}

首先,我将.postDelayed更改为.post。然后,为了将操作延迟一秒,我在Thread.sleep(1000)内但在for (...)外面添加了new Handler(Looper.getMainLooper()).post(...));

现在,应用程序可以在后台执行该过程,而用户仍然可以与UI进行交互。谢谢。