[英]Removing location updates using a thread
我有一項服務,該服務會不斷輪詢Web服務的某些選項。 這些選項基本上會重新啟動LocationManager。 重新啟動是使用自定義事件完成的,該事件是從線程內部使用的方法中觸發的。
這是我的自定義事件
public class OptionsChangedEvent extends EventObject {
public OptionsChangedEvent(Object o){
super(o);
}
}
和自定義監聽器
public interface OptionsChangedListener extends EventListener {
public void optionsChanged(OptionsChangedEvent evt);
}
在服務中運行並輪詢新選項的線程如下
private Thread optionsThread = new Thread() {
public void run() {
//Looper.prepare();
while(true) {
String opts = getOptsFromServer();
if(!opts.equals(currentOpts)) updateOpts(opts); //the prob is here
//Looper.loop();
Thread.sleep(10 * 1000) // sleep 10sec
}
}
}
最后,這是我如何在跟蹤器中實現偵聽器。
locOpts.addOptionsChangedListener(new OptionsChangedListener() {
@Override
public void optionsChanged(OptionsChangedEvent event) {
Log.d("LOCATION_OPTIONS_CHANGED", "SUCCESS");
mLocationManager.removeUpdates(mLocationListener);
mLocationManager.requestLocationUpdates(
provider,
update,
0, mLocationListener
);
}
});
我遇到以下錯誤,該錯誤基本上表明我需要在線程內使用Looper.loop
和Looper.prepare
。
12-03 11:31:39.544 26751-26843/com.test.location E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-10370
Process: com.test.location, PID: 26751
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:221)
at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:221)
at android.location.LocationManager.wrapListener(LocationManager.java:844)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:857)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:454)
at com.test.location.trackers.LocationTracker$2.optionsChanged(LocationTracker.java:93)
at com.test.location.options.LocationTrackerOptions.notifyListeners(LocationTrackerOptions.java:22)
at com.test.location.options.LocationTrackerOptions.fromJSON(LocationTrackerOptions.java:34)
at com.test.location.MainService$5.run(MainService.java:219)
如果我取消注釋Looper部件,則該線程只能工作一次,而我無法弄清為什么會發生這種情況。
經過一番調查,我發現該代碼需要消息隊列並造成了此問題。 是否有人需要做這樣的事情? 如果可以的話,我不想在這里更改設計。
private synchronized void notifyListeners(Object obj) {
for (OptionsChangedListener listener : listeners) {
listener.optionsChanged(new OptionsChangedEvent(obj));
}
}
您是否嘗試在回調方法updateOpts中更新UI?
如果要從UI線程將任務發送到backround線程,則Looper使用其他方式進行准備和循環,以便將消息發送到該線程,並在線程內部處理Handler的handlemessage事件中的消息。
嘗試避免直接從線程中進行UI調用,也可以嘗試使用runOnUIThread(...)或AsyncTasks onPost對UI線程進行適當的回調。
該解決方案實際上非常簡單。 我缺少回調函數。
locOpts.addOptionsChangedListener(new OptionsChangedListener() {
@Override
public void optionsChanged(OptionsChangedEvent event) {
Log.d("LOCATION_OPTIONS_CHANGED", "SUCCESS");
mLocationManager.removeUpdates(mLocationListener);
mLocationManager.requestLocationUpdates(
provider,
update,
0, mLocationListener,
Looper.getMainLooper() // this was the problem
);
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.