Search code examples
androidandroid-serviceandroid-service-binding

Android service run multiple


This is my service code:

public class MyCustomService extends Service {
public static final String INPUT_TEXT="INPUT_TEXT";
public static final String OUTPUT_TEXT="OUTPUT_TEXT";
private volatile HandlerThread mHandlerThread;
private ServiceHandler mServiceHandler;
public Socket client;

// ...

// Define how the handler will process messages
private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    // Define how to handle any incoming messages here
    @Override
    public void handleMessage(Message message) {
        // ...
        // When needed, stop the service with
        // stopSelf();
    }
}

// Fires when a service is first initialized
public void onCreate() {
    super.onCreate();
    // An Android handler thread internally operates on a looper.
    mHandlerThread = new HandlerThread("MyCustomService.HandlerThread");
    mHandlerThread.start();
    // An Android service handler is a handler running on a specific background thread.
    mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());

}


// Fires when a service is started up
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Send empty message to background thread
    mServiceHandler.sendEmptyMessageDelayed(0, 500);
    // or run code in background
    mServiceHandler.post(new Runnable() {
        @Override
        public void run() {
            // Do something here in background!

            IO.Options opts = new IO.Options();
            opts.query = "auth_token=51";
            try {
                client = IO.socket("http://192.168.0.106:3000/",opts);
                client.on("message", onMessage);
                client.connect();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }


            // If desired, stop the service
            //stopSelf();
        }
    });
    // Keep service around "sticky"
    return START_STICKY;
}

// ...

// Defines the shutdown sequence
@Override
public void onDestroy() {
    // Cleanup service before destruction
    client.disconnect();
    client.close();
    mHandlerThread.quit();
}

private Emitter.Listener onMessage = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        String message = (String) args[0];
        Log.d("recive message message message", message);

        /*create new intent to broadcast our processed data to our activity*/
        Intent resultBroadCastIntent = new Intent();
        /*set action here*/
        //resultBroadCastIntent.setAction(TextCapitalizeResultReceiver.ACTION_TEXT_CAPITALIZED);
        resultBroadCastIntent.setAction(Intent.ACTION_SEND);
        /*set intent category as default*/
        // resultBroadCastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        /*add data to intent*/
        resultBroadCastIntent.putExtra(OUTPUT_TEXT, message);
        /*send broadcast */
        sendBroadcast(resultBroadCastIntent);

    }
};


@Override
public IBinder onBind(Intent intent) {
    return null;
}
}

And I run it from activity this code in onCreate:

    Intent i = new Intent(this, MyCustomService.class);

    i.putExtra("foo", "bar");

    startService(i);

My problem is that every time I enter main Activity and it run service twice or 3 or 4 times so when I receive new message by socket it's received same message three or four times.


Solution

  • You should first check if the service is already running, if not then only run the service.

    /**
         * @param serviceClass Class name of Service
         * @return - boolean indicating running status of Service
         */
        public static boolean isServiceRunning(Context context, Class<?> serviceClass) {
            ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
                if (serviceClass.getName().equals(service.service.getClassName())) {
                    return true;
                }
            }
            return false;
        }
    

    Also, if you are saving the messages in database you should put check against the message id so the duplicate message doesn't stack up there. There will be many cases where the socket when connected will try sending you the already received message.