diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2014-03-26 15:19:03 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2014-03-26 15:19:03 +0100 |
| commit | b6e28fc56d7517116bfa9e13fcfd0424de26e04a (patch) | |
| tree | a17ffb6f1eda4c7e6b2d236643157cd19e2f55ff /main/src/cgeo/geocaching/sensors | |
| parent | 6dd33e492d9123334ec0546414e574bbb10ad760 (diff) | |
| download | cgeo-b6e28fc56d7517116bfa9e13fcfd0424de26e04a.zip cgeo-b6e28fc56d7517116bfa9e13fcfd0424de26e04a.tar.gz cgeo-b6e28fc56d7517116bfa9e13fcfd0424de26e04a.tar.bz2 | |
Put out as much sensor work as possible onto background threads
The sensors signals and merging are now delivered on background handler
threads instead of the UI thread.
While this might not change a lot of things in practice, it may help
with #3680.
Diffstat (limited to 'main/src/cgeo/geocaching/sensors')
| -rw-r--r-- | main/src/cgeo/geocaching/sensors/DirectionProvider.java | 91 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/sensors/GeoDataProvider.java | 12 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/sensors/GeoDirHandler.java | 4 |
3 files changed, 60 insertions, 47 deletions
diff --git a/main/src/cgeo/geocaching/sensors/DirectionProvider.java b/main/src/cgeo/geocaching/sensors/DirectionProvider.java index 162f14c..8efbc1f 100644 --- a/main/src/cgeo/geocaching/sensors/DirectionProvider.java +++ b/main/src/cgeo/geocaching/sensors/DirectionProvider.java @@ -1,15 +1,13 @@ package cgeo.geocaching.sensors; +import android.os.Process; import cgeo.geocaching.compatibility.Compatibility; +import cgeo.geocaching.utils.StartableHandlerThread; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Subscriber; -import rx.Subscription; -import rx.observables.ConnectableObservable; import rx.subjects.BehaviorSubject; -import rx.subscriptions.Subscriptions; -import rx.functions.Action0; import android.app.Activity; import android.content.Context; @@ -17,39 +15,24 @@ import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; +import android.os.*; -public class DirectionProvider implements OnSubscribe<Float> { +public class DirectionProvider { - private final SensorManager sensorManager; - private final BehaviorSubject<Float> subject = BehaviorSubject.create(0.0f); + private static final BehaviorSubject<Float> subject = BehaviorSubject.create(0.0f); - static public Observable<Float> create(final Context context) { - return new DirectionProvider((SensorManager) context.getSystemService(Context.SENSOR_SERVICE)).worker.refCount(); - } + static class Listener implements SensorEventListener, StartableHandlerThread.Callback { - private DirectionProvider(final SensorManager sensorManager) { - this.sensorManager = sensorManager; - } + private int count = 0; + private SensorManager sensorManager; - @Override - public void call(final Subscriber<? super Float> subscriber) { - subject.distinctUntilChanged().subscribe(subscriber); - } + @Override + public void onSensorChanged(final SensorEvent event) { + subject.onNext(event.values[0]); + } - private final ConnectableObservable<Float> worker = new ConnectableObservable<Float>(this) { @Override - public Subscription connect() { - @SuppressWarnings("deprecation") - // This will be removed when using a new location service. Until then, it is okay to be used. - final Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); - final SensorEventListener listener = new SensorEventListener() { - @Override - public void onSensorChanged(final SensorEvent event) { - subject.onNext(event.values[0]); - } - - @Override - public void onAccuracyChanged(final Sensor sensor, final int accuracy) { + public void onAccuracyChanged(final Sensor sensor, final int accuracy) { /* * There is a bug in Android, which apparently causes this method to be called every * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging @@ -60,19 +43,43 @@ public class DirectionProvider implements OnSubscribe<Float> { * See for example https://code.google.com/p/android/issues/detail?id=14792 */ - //Log.i(Settings.tag, "Compass' accuracy is low (" + accuracy + ")"); - } - }; - - sensorManager.registerListener(listener, defaultSensor, SensorManager.SENSOR_DELAY_NORMAL); - return Subscriptions.create(new Action0() { - @Override - public void call() { - sensorManager.unregisterListener(listener); - } - }); + //Log.i(Settings.tag, "Compass' accuracy is low (" + accuracy + ")"); } - }; + + // This will be removed when using a new location service. Until then, it is okay to be used. + @SuppressWarnings("deprecation") + @Override + public void start(final Context context, final Handler handler) { + if (++count == 1) { + sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL, handler); + } + } + + @Override + public void stop() { + if (--count == 0) { + sensorManager.unregisterListener(this); + } + } + + } + + private static final StartableHandlerThread handlerThread = + new StartableHandlerThread("DirectionProvider thread", Process.THREAD_PRIORITY_BACKGROUND, new Listener()); + static { + handlerThread.start(); + } + + static public Observable<Float> create(final Context context) { + return Observable.create(new OnSubscribe<Float>() { + @Override + public void call(final Subscriber<? super Float> subscriber) { + handlerThread.start(subscriber, context); + subject.subscribe(subscriber); + } + }); + } /** * Take the phone rotation (through a given activity) in account and adjust the direction. diff --git a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java index 160d98d..a77b477 100644 --- a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java +++ b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java @@ -1,7 +1,9 @@ package cgeo.geocaching.sensors; +import android.os.*; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.StartableHandlerThread; import org.apache.commons.lang3.StringUtils; import rx.Observable; import rx.Observable.OnSubscribe; @@ -22,7 +24,6 @@ import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; -import android.os.Bundle; import java.util.concurrent.TimeUnit; @@ -33,6 +34,11 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { private final LocationData gpsLocation = new LocationData(); private final LocationData netLocation = new LocationData(); private final BehaviorSubject<IGeoData> subject; + private static final StartableHandlerThread handlerThread = + new StartableHandlerThread("GeoDataProvider thread", android.os.Process.THREAD_PRIORITY_BACKGROUND); + static { + handlerThread.start(); + } public boolean gpsEnabled = false; public int satellitesVisible = 0; @@ -92,7 +98,7 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { @Override public Subscription connect() { final CompositeSubscription subscription = new CompositeSubscription(); - AndroidSchedulers.mainThread().schedule(new Action1<Inner>() { + AndroidSchedulers.handlerThread(handlerThread.getHandler()).schedule(new Action1<Inner>() { @Override public void call(final Inner inner) { synchronized(lock) { @@ -112,7 +118,7 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { subscription.add(Subscriptions.create(new Action0() { @Override public void call() { - AndroidSchedulers.mainThread().schedule(new Action1<Inner>() { + AndroidSchedulers.handlerThread(handlerThread.getHandler()).schedule(new Action1<Inner>() { @Override public void call(final Inner inner) { synchronized (lock) { diff --git a/main/src/cgeo/geocaching/sensors/GeoDirHandler.java b/main/src/cgeo/geocaching/sensors/GeoDirHandler.java index 0af2cc8..588bd84 100644 --- a/main/src/cgeo/geocaching/sensors/GeoDirHandler.java +++ b/main/src/cgeo/geocaching/sensors/GeoDirHandler.java @@ -42,12 +42,12 @@ public abstract class GeoDirHandler { * preferences allow it). */ public Subscription start() { - return app.geoDirObservable().subscribe(new Action1<ImmutablePair<IGeoData, Float>>() { + return app.geoDirObservable().observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<ImmutablePair<IGeoData, Float>>() { @Override public void call(final ImmutablePair<IGeoData, Float> geoDir) { handleGeoDir(geoDir); } - }, AndroidSchedulers.mainThread()); + }); } } |
