aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/utils/StartableHandlerThread.java
blob: 91ab1d09183182f8ca9134004e08b04d22f98a94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package cgeo.geocaching.utils;

import org.eclipse.jdt.annotation.NonNull;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;

/**
 * Derivated class of {@link android.os.HandlerThread} with an exposed handler and a start/stop mechanism
 * based on subscriptions.
 */

public class StartableHandlerThread extends HandlerThread {

    private final static int START = 1;
    private final static int STOP = 2;

    static public interface Callback {
        public void start(final Context context, final Handler handler);
        public void stop();
    }

    // The handler and the thread are intimely linked, there will be no leak.
    @SuppressLint("HandlerLeak")
    private class StartableHandler extends Handler {
        public StartableHandler() {
            super(StartableHandlerThread.this.getLooper());
        }

        @Override
        public void handleMessage(final Message message) {
            if (callback != null) {
                switch (message.what) {
                    case START:
                        callback.start((Context) message.obj, this);
                        break;
                    case STOP:
                        callback.stop();
                        break;
                }
            }
        }
    }

    private Handler handler;
    private Callback callback;

    public StartableHandlerThread(@NonNull final String name, final int priority, final Callback callback) {
        super(name, priority);
        this.callback = callback;
    }

    public StartableHandlerThread(@NonNull final String name, final int priority) {
        this(name, priority, null);
    }

    public synchronized Handler getHandler() {
        if (handler == null) {
            handler = new StartableHandler();
        }
        return handler;
    }

    public void start(final Subscriber<?> subscriber, final Context context) {
        getHandler().obtainMessage(START, context).sendToTarget();
        subscriber.add(Subscriptions.create(new Action0() {
            @Override
            public void call() {
                getHandler().sendEmptyMessage(STOP);
            }
        }));
    }

}