簡體   English   中英

使用線程刪除位置更新

[英]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.loopLooper.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM