Android Start/Stop Service using HandlerThread

By Arvind Rai, July 14, 2015
On this page, we will walk through Android start and stop Service from Activity using HandlerThread. Service runs in background and does not interact with user interface. The use of service is to run long operation like downloading content. If starting application switches to another application, still our service is running in background. Normally service does not return result to starting application. Service can be started and stopped from Activity using startService(intent) and stopService(intent) respectively by passing Intent. Service starts a new thread to run in background. Android provides HandlerThread class to start a thread with Looper. In our example we will provide a demo to start and stop service from Activity and service will log a message after every second while running in background.

android.app.Service

android.app.Service runs the long running process in background. Service does not interact to user. It will run in background even if the user switches to another application. While using Service we need to override methods. Some of them are as follows.
onCreate() : System calls it when service is first created. We can use it to initialize values for process.
onStartCommand(Intent intent, int flags, int startId) : System calls it when service is started explicitly. For every service start call, it is called.
onBind(Intent): It is used for inter process communication(IPC). It returns null if clients can not bind to service.
onDestroy(): System calls it when service is completed or stopped. We can use it for resource cleanup purpose.

Service can stop itself by calling methods as follows.
stopSelf(): On calling it, Service is stopped if it is running.
stopSelfResult(int startId): Stops the service for the most recent start id.

Find some constants which are returned from onStartCommand(Intent, int, int).
START_STICKY : It starts the onStartCommand if killed while stating.
START_NOT_STICKY : If service is killed while starting, it does not restart until explicitly service is started.
START_REDELIVER_INTENT : If service is killed while starting, it will schedule to restart with latest intent.

To use service we need to configure it in AndroidManifest.xml within application tag.
<service android:name=".MyService"/>
 

Start/Stop Service from Activity

To start and stop service from Activity, we need to create Intent first for our Service. To start the service, call startService(intent) and to stop the service, call stopService(intent).
Intent intent = new Intent(MainActivity.this, MyService.class);	
startService(intent);
stopService(intent);  

HandlerThread

android.os.HandlerThread creates a new thread with Looper which is used to create handler class. It extends java.lang.Thread. To start it we need to call start() method. This class provides getLooper() which returns Looper of that thread.

Complete Example


MyService.java
package com.concretepage;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
	  private static final String TAG = "MyService";
	  private boolean isRunning  = false;
	  private Looper looper;
	  private MyServiceHandler myServiceHandler;
	  @Override
	  public void onCreate() {
	    HandlerThread handlerthread = new HandlerThread("MyThread", Process.THREAD_PRIORITY_BACKGROUND);
	    handlerthread.start();
	    looper = handlerthread.getLooper();
	    myServiceHandler = new MyServiceHandler(looper);
            isRunning = true;
	  }
	  @Override
	  public int onStartCommand(Intent intent, int flags, int startId) {
	      Message msg = myServiceHandler.obtainMessage();
	      msg.arg1 = startId;
	      myServiceHandler.sendMessage(msg);
	      Toast.makeText(this, "MyService Started.", Toast.LENGTH_SHORT).show();
	      //If service is killed while starting, it restarts. 
	      return START_STICKY;
	  }
	  @Override
	  public IBinder onBind(Intent intent) {
	      return null;
	  }
	  @Override
	  public void onDestroy() {
	    isRunning = false;  
	    Toast.makeText(this, "MyService Completed or Stopped.", Toast.LENGTH_SHORT).show();
	  }
	  private final class MyServiceHandler extends Handler {
	      public MyServiceHandler(Looper looper) {
	          super(looper);
	      }
	      @Override
	      public void handleMessage(Message msg) {
                synchronized (this) {
            	  for (int i = 0; i < 10; i++) {
                      try {
                          Log.i(TAG, "MyService running...");
                          Thread.sleep(1000);
                      } catch (Exception e) {
                    	  Log.i(TAG, e.getMessage());
                      }
                      if(!isRunning){
                    	  break;
                      } 
                  }
               }
               //stops the service for the start id.
	       stopSelfResult(msg.arg1);
	     }
	  }
	} 

MainActivity.java
package com.concretepage;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        OnClickListener listener = new OnClickListener() {
    	    public void onClick(View view) {
    	        Intent intent = new Intent(MainActivity.this, MyService.class);	
		        switch (view.getId()) {
		            case R.id.service_start:
		            	//starts service for the given Intent 
		                startService(intent);
		                break;
		            case R.id.service_stop:
		            	//stops service for the given Intent
		                stopService(intent);
		                break;
                        }
            }
    	};
    	findViewById(R.id.service_start).setOnClickListener(listener);
    	findViewById(R.id.service_stop).setOnClickListener(listener);
    }
} 

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#C98C00"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/service_start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_start" />
    <Button
        android:id="@+id/service_stop"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_stop" />
</LinearLayout> 

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.concretepage"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="11"/>
    <application
        android:allowBackup ="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity  android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MyService"/>
    </application>
</manifest> 

Output

Android Start/Stop Service from Activity Example using HandlerThread
Find the output in LogCat.
07-14 15:13:25.070: I/MyService(756): MyService running...
07-14 15:13:26.080: I/MyService(756): MyService running...
07-14 15:13:27.110: I/MyService(756): MyService running...
07-14 15:13:28.110: I/MyService(756): MyService running...
-------------------------------------------------------
------------------------------------------------------- 

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us