![](/img/trans.png)
[英]Using Thread/Handler/Looper for Worker Thread Android
[英]Using a looper on a separate thread in Android
背景:
我正在嘗試通過handler.postDelayed
逐漸移動標記,直到它從一個停靠點到達下一個停靠點,來顯示總線的運動。
我希望它在一定時間后重復到下一個停止,所以我嘗試在單獨的線程上使用循環程序,因為這對於主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)
沒有辦法確定您的handler1變量是從哪個線程創建的。 確保它在UI線程上。 或快速修復:
handler1 = new Handler(context.getApplicationContext().getMainLooper());
您的方法moveBusMarker()在后台線程中運行,這就是您收到此錯誤的原因。 嘗試AsyncTask類。 使用doInBackground方法運行循環程序,然后在postExecute方法中更新UI。
Handler handler = new Handler(Looper.getMainLooper());
應該解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.