Why does my service start twice?

Why does my service start twice? I am returning START_STICKY.

I install it from Eclipse using Run As and run it in a windows console window:

D:\>adb shell am startservice --user 0 -a android.intent.action.MAIN -n "com.sandbox.mq/.MainService"
Starting service: Intent { act=android.intent.action.MAIN cmp=com.sandbox.mq/.MainService }

      

In the Logcat window, I can see that it was launched twice !

09-07 21:49:19.427: D/MQ(14027): Hi, the system is up! Today is: Sep 7, 2014 9:49:19 PM
09-07 21:49:19.427: V/MQ(14027): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-07 21:49:19.427: V/MQ(14027): BackgroundThread0. Thread id = 866 sent message 0
09-07 21:49:19.427: V/MQ(14027): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-07 21:49:19.437: V/MQ(14027): BackgroundThread0. Thread id = 869 sent message 0
09-07 21:49:19.437: V/MQ(14027): MessageHandler on thread Thread id = 1 received message 0
09-07 21:49:19.437: V/MQ(14027): MessageHandler on thread Thread id = 1 received message 0

      

When I install from adb it still runs twice, but the output is different:

adb install MQ.apk

      

-

09-07 22:07:28.567: D/MQ(14642): Hi, the system is up! Today is: Sep 7, 2014 10:07:28 PM
09-07 22:07:28.567: V/MQ(14642): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-07 22:07:28.577: V/MQ(14642): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-07 22:07:28.577: V/MQ(14642): BackgroundThread0. Thread id = 872 sent message 0
09-07 22:07:28.577: V/MQ(14642): MessageHandler on thread Thread id = 1 received message 0

      

com.sandbox.mq package;

public class StartMainService extends Application {
    final static String TAG = "MQ";

    public void onCreate() {
        super.onCreate();
        Context context = getApplicationContext();
        Log.d(TAG, "Hi, the system is up! Today is: " + DateFormat.getDateTimeInstance().format(new Date()));
        Intent startServiceIntent = new Intent(context, MainService.class);
        context.startService(startServiceIntent);
    }
}

      

-

public class MainService extends Service {
    final static String TAG = "MQ";
    BackgroundThread0 bthread0;
    BackgroundThread1 bthread1;

    public class MqBinder extends Binder {
        public MqBinder(Context ctxt) {
            Log.v(TAG, "MqBinder() " + "Thread id = "
                    + Thread.currentThread().getId());
        }
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return new MqBinder(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "onStartCommand(). I am INSIDE THE main sERVICE "
                + "Thread id = " + Thread.currentThread().getId());
        bthread0 = new BackgroundThread0();
        if (!bthread0.isAlive()) {
            bthread0.start();
        } else {
            Log.v(TAG, "onStartCommand(). bthread0 was already started");
        }
        bthread1 = new BackgroundThread1();
        if (!bthread1.isAlive()) {
            bthread1.start();
        } else {
            Log.v(TAG, "onStartCommand(). bthread1 was already started");
        }
        return START_STICKY;
    }

    private class BackgroundThread0 extends Thread {
        Handler b1Handler;

        @Override
        public void run() {
            super.run();
            b1Handler = bthread1.b1Handler;
            Message msg = b1Handler.obtainMessage(MessageHandler.TYPE0);
            b1Handler.sendMessage(msg);
            Log.v(TAG, "BackgroundThread0. " + "Thread id = "
                    + Thread.currentThread().getId() + " sent message "
                    + msg.what);
        }

    }

    private class BackgroundThread1 extends Thread {
        public BackgroundThread1() {
            super();
            b1Handler = new MessageHandler();
        }

        Handler b1Handler;

        @Override
        public void run() {
            super.run();
            Looper.prepare();
            Looper.loop();
        }

    }

    private static class MessageHandler extends Handler {
        static final int TYPE0 = 0;
        static final int TYPE1 = 1;
        static final int TYPE2 = 2;

        public MessageHandler() {

        }

        @Override
        public void handleMessage(Message msg) {
            Log.v(TAG, "MessageHandler on thread " + "Thread id = "
                    + Thread.currentThread().getId() + " received message "
                    + msg.what);

            switch (msg.what) {
            case TYPE0:
                break;
            case TYPE1:
                break;
            case TYPE2:
                break;
            }
            super.handleMessage(msg);
        }
    }
}

      

-

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sandbox.mq" >

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <application
        android:name="com.sandbox.mq.StartMainService"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:persistent="true"
        android:theme="@style/AppTheme" >
        <service android:name="com.sandbox.mq.MainService" android:exported="true"> 
             <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>          
        </service>        
    </application>

</manifest>

      

Update:

From Ian's answer below, when I comment out the call to startService in onCreate, it is only called once.

09-08 09:29:10.393: D/MQ(4746): Hi, the system is up! Today is: Sep 8, 2014 9:29:10 AM
09-08 09:29:10.393: V/MQ(4746): onStartCommand(). I am INSIDE THE main sERVICE Thread id = 1
09-08 09:29:10.393: V/MQ(4746): BackgroundThread0. Thread id = 1050 sent message 0
09-08 09:29:10.393: V/MQ(4746): MessageHandler on thread Thread id = 1 received message 0

      

My original question was answered, but I'm wondering ... Why does BackgroundThread1 have the same thread id as the main service thread id = 1?

+3


source to share


1 answer


It runs twice because you start it twice:

  • adb shell am startservice

    starts the service
  • The process starts by starting yours Application

    onCreate()

    , which also starts the service.


onStartCommand

called every time something starts your service. If you want something to be done only once for the lifecycle of your service, you should do it in your service, onCreate()

or check before re-working in onStartCommand

(i.e. Check if the value bthread0

is null before creating / start it again ).

+9


source