背景
我试图通过handler.postDelayed
逐渐移动标记来显示公交车的移动,直到它从一站到达下一站。
我希望它在一段时间后重复下一站,所以我尝试在一个单独的线程上使用一个looper,因为它对主UI线程来说太多了。
问题:
因为我正在更新标记的位置,所以我需要在每秒后为它设置一个新位置,但是在运行代码时我会遇到错误,指出它不在主UI线程上(参见底部的这篇文章)。
错误指向存储busMarker的变量,我假设它只能由创建它的线程修改。
我已经尝试了runOnUiThread()
,但我仍然会遇到其他错误,例如因为我为其分配值而不是主线程中的空值。
我假设有一种比连续返回主线程更清洁的方式,那么我该如何实现呢?
创建主题
private class ThreadClass extends Thread {
@Override
public void run() {
Looper.prepare();
moveBusMarker();
if (passedStops.size() != stops.size()) {
Looper.loop();
}
else {
Looper.myLooper().quit();
}
}
}
运行主题
if (passedStops.size() != 0 && passedStops.size() != stops.size()) {
thread.start();
}
执行动作
// set up a timer
final long limit = TimeUnit.SECONDS.toMillis(seconds) - 1000;
final long startTime = System.currentTimeMillis();
final Stop NextStop = nextStop;
final Handler handler1 = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d("", "The bus is currently at " + busPosition.toString());
// get the current bus' position
double lat = busPosition.latitude;
double lon = busPosition.longitude;
// add the difference to the bus position to move it closer
lat = lat + latDifference;
lon = lon + lonDifference;
busPosition = new LatLng(lat, lon);
Log.d("", "The bus has moved to " + busPosition.toString());
// set the new position to the marker representing the bus movement
busMarker.setPosition(busPosition);
// it hasn't reached the next stop, continue to animate
if ((System.currentTimeMillis() - startTime) < limit) {
handler1.postDelayed(this, 1000);
}
// else the time is up i.e. the bus has reached the next stop, so set the new target
else {
Log.d("", "The bus has passed " + NextStop.getName());
passedStops.add(NextStop);
Log.d("", passedStops.toString());
createPolyline();
}
}
};
handler1.post(runnable);
记录错误
Process: com.example.sanj.fyp, PID: 18904
java.lang.IllegalStateException: Not on the main thread
at com.google.l.a.cd.b(Unknown Source)
at com.google.maps.api.android.lib6.c.ca.a(Unknown Source)
at com.google.maps.api.android.lib6.c.aj.a(Unknown Source)
at com.google.android.gms.maps.model.internal.t.onTransact(SourceFile:73)
at android.os.Binder.transact(Binder.java:361)
at com.google.android.gms.maps.model.internal.l$a$a.setPosition(Unknown Source)
at com.google.android.gms.maps.model.Marker.setPosition(Unknown Source)
at com.example.sanj.fyp.main.fragment.LiveServiceFragment$2$1.run(LiveServiceFragment.java:423)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at com.example.sanj.fyp.main.fragment.LiveServiceFragment$ThreadClass.run(LiveServiceFragment.java:115)
答案 0 :(得分:1)
没有办法计算创建handler1变量的线程。确保它在UI线程上。或者快速修复:
handler1 = new Handler(context.getApplicationContext().getMainLooper());
答案 1 :(得分:0)
您的方法moveBusMarker()在后台线程中运行,这就是您收到此错误的原因。 试试AsyncTask课程。使用doInBackground方法运行looper,然后使用postExecute方法更新UI。
答案 2 :(得分:0)
Handler handler = new Handler(Looper.getMainLooper());
应该解决你的问题。