Search This Blog

Showing posts with label Service. Show all posts
Showing posts with label Service. Show all posts

Tuesday, 30 December 2014

Best practices Android Resposiveness : Using background Intent service for background job

An IntentService isn't affected by most user interface lifecycle events, so it continues to run in circumstances that would shut down an AsyncTask.

Creating a background services

Create a class RSSPullService and extends IntentService to create component IntentService



          public class RSSPullService extends IntentService {
    @Override
    protected void onHandleIntent(Intent workIntent) {
        // Gets data from the incoming Intent
        String dataString = workIntent.getDataString();
        ...
        // Do work here, based on the contents of dataString
        ...
    }
}
       
 

Define IntentService with application Manifest


Create a background work request and send it to IntentService

Create a new, explicit Intent for the IntentService called RSSPullService.

mServiceIntent = new Intent(getActivity(), RSSPullService.class);
mServiceIntent.setData(Uri.parse(dataUrl));

Call startService()

// Starts the IntentService
getActivity().startService(mServiceIntent);

Report Status from an IntentService See Google Android Article 

Download Source


Saturday, 4 May 2013

How to make Android service unstoppable and run it continuously

Android service runs in different mode with help of flag e.g START_CONTINUATION_MASK, START_NOT_STICKY. It enable to control the behavior of Android service life. But service will work until user allow it work. If he/she stops it, it will destroy automatically. More than often, we required it to run unstoppable  If in case user stop, re-instance the old service instance.
For some people, it may malware but sometimes we have to full filled client requirement and that's all our purpose is.

Case when your service can be stopped



  • User stop it forcefully
  • Low Memory situation
  • Device restarted


Handling first two case


When ever we stop service forcefully (or os kill it), it will call onDestory() method. First concept is to use one receiver and send one broadcast whenever service destroy. And restarted service again.

Third case if device is restarted then already we had onBootCompleted action for receiver to catch

Lets go steps by Step to make our Android Service unstoppable

Step 1) Create one Android BroadCastReciever and register it for two action


Manifest

        <service android:name="ServiceTest" >
        </service>

        <receiver android:name="ReceiverCall" >
            <intent-filter>
                <action android:name="com.android.techtrainner" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

com.android.techtrainner is the custom action. BroadCastReceiver Class contain code to restart service again

public class ReceiverCall extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("Service Stops", "Ohhhhhhh");
        context.startService(new Intent(context, ServiceTest.class));;
    }

}


Step 2) Create Android service class , do some task there (I have taken one Timer to print Log) and in onDestory()


    public void onDestroy() {
        try {
            mTimer.cancel();
            timerTask.cancel();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Intent intent = new Intent("com.android.techtrainner");
        intent.putExtra("yourvalue", "torestore");
        sendBroadcast(intent);
    }

Run your application and go to setting, See running service, you will TestService. Try to close it , ohhhhhh it will not close.

DownloadSource Application



Wednesday, 13 March 2013

Binding service using Android Interface DefinitionLanguage (.aidl) in android

Binding service using iBinder an Messanger already discussesd. Third and most complicated way is binding service using Android Interface Definition Language (AIDL). Its rarely use and hard to implement. So this post simply will show you how to create one connection using Android Interface Definition Language (AIDL) between activity and service

 When to use Android Interface Definition Language (AIDL)

Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Knowledge Required you should read about binding service using IBinder and Messanger

 Steps 1) create .aidl interface. Create one file name IRemoteService.aidl and keep inside your main package


 // IRemoteService.aidl  
 package com.example.locationmanager;  
 // Declare any non-default types here with import statements  
 /** Example service interface */  
 interface IRemoteService {  
 /** Request the process ID of this service, to do evil things with it. */  
 int getPid();  
 /** Demonstrates some basic types that you can use as parameters  
 * and return values in AIDL.  
 */  
 void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,  
 double aDouble, String aString);  
 }  

When you build your application IRemoteService.aidl changes into IRemoteService.java like this. You can find this inside bin folder

 // Declare any non-default types here with import statements  
 /** Example service interface */  
 public interface IRemoteService extends android.os.IInterface {  
 /** Local-side IPC implementation stub class. */  
 public static abstract class Stub extends android.os.Binder implements  
 com.example.locationmanager.IRemoteService {  
 private static final java.lang.String DESCRIPTOR = "com.example.locationmanager.IRemoteService";  
 /** Construct the stub at attach it to the interface. */  
 public Stub() {  
 this.attachInterface(this, DESCRIPTOR);  
 }  
 /**  
 * Cast an IBinder object into an  
 * com.example.locationmanager.IRemoteService interface, generating a  
 * proxy if needed.  
 */  
 public static com.example.locationmanager.IRemoteService asInterface(  
 android.os.IBinder obj) {  
 if ((obj == null)) {  
 return null;  
 }  
 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);  
 if (((iin != null) && (iin instanceof com.example.locationmanager.IRemoteService))) {  
 return ((com.example.locationmanager.IRemoteService) iin);  
 }  
 return new com.example.locationmanager.IRemoteService.Stub.Proxy(  
 obj);  
 }  
 @Override  
 public android.os.IBinder asBinder() {  
 return this;  
 }  
 @Override  
 public boolean onTransact(int code, android.os.Parcel data,  
 android.os.Parcel reply, int flags)  
 throws android.os.RemoteException {  
 switch (code) {  
 case INTERFACE_TRANSACTION: {  
 reply.writeString(DESCRIPTOR);  
 return true;  
 }  
 case TRANSACTION_getPid: {  
 data.enforceInterface(DESCRIPTOR);  
 int _result = this.getPid();  
 reply.writeNoException();  
 reply.writeInt(_result);  
 return true;  
 }  
 case TRANSACTION_basicTypes: {  
 data.enforceInterface(DESCRIPTOR);  
 int _arg0;  
 _arg0 = data.readInt();  
 long _arg1;  
 _arg1 = data.readLong();  
 boolean _arg2;  
 _arg2 = (0 != data.readInt());  
 float _arg3;  
 _arg3 = data.readFloat();  
 double _arg4;  
 _arg4 = data.readDouble();  
 java.lang.String _arg5;  
 _arg5 = data.readString();  
 this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);  
 reply.writeNoException();  
 return true;  
 }  
 }  
 return super.onTransact(code, data, reply, flags);  
 }  
 private static class Proxy implements  
 com.example.locationmanager.IRemoteService {  
 private android.os.IBinder mRemote;  
 Proxy(android.os.IBinder remote) {  
 mRemote = remote;  
 }  
 @Override  
 public android.os.IBinder asBinder() {  
 return mRemote;  
 }  
 public java.lang.String getInterfaceDescriptor() {  
 return DESCRIPTOR;  
 }  
 /**  
 * Request the process ID of this service, to do evil things with  
 * it.  
 */  
 @Override  
 public int getPid() throws android.os.RemoteException {  
 android.os.Parcel _data = android.os.Parcel.obtain();  
 android.os.Parcel _reply = android.os.Parcel.obtain();  
 int _result;  
 try {  
 _data.writeInterfaceToken(DESCRIPTOR);  
 mRemote.transact(Stub.TRANSACTION_getPid, _data, _reply, 0);  
 _reply.readException();  
 _result = _reply.readInt();  
 } finally {  
 _reply.recycle();  
 _data.recycle();  
 }  
 return _result;  
 }  
 /**  
 * Demonstrates some basic types that you can use as parameters and  
 * return values in AIDL.  
 */  
 @Override  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, java.lang.String aString)  
 throws android.os.RemoteException {  
 android.os.Parcel _data = android.os.Parcel.obtain();  
 android.os.Parcel _reply = android.os.Parcel.obtain();  
 try {  
 _data.writeInterfaceToken(DESCRIPTOR);  
 _data.writeInt(anInt);  
 _data.writeLong(aLong);  
 _data.writeInt(((aBoolean) ? (1) : (0)));  
 _data.writeFloat(aFloat);  
 _data.writeDouble(aDouble);  
 _data.writeString(aString);  
 mRemote.transact(Stub.TRANSACTION_basicTypes, _data,  
 _reply, 0);  
 _reply.readException();  
 } finally {  
 _reply.recycle();  
 _data.recycle();  
 }  
 }  
 }  
 static final int TRANSACTION_getPid = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);  
 static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);  
 }  
 /** Request the process ID of this service, to do evil things with it. */  
 public int getPid() throws android.os.RemoteException;  
 /**  
 * Demonstrates some basic types that you can use as parameters and return  
 * values in AIDL.  
 */  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, java.lang.String aString)  
 throws android.os.RemoteException;  
 }  

Step 2) Implement IRemoteService.aidl inside your service. So first create one service class name AidlService.java here

 import android.app.Service;  
 import android.content.Intent;  
 import android.os.IBinder;  
 import android.os.RemoteException;  
 public class AidlService extends Service {  
 @Override  
 public void onCreate() {  
 super.onCreate();  
 }  
 @Override  
 public IBinder onBind(Intent arg0) {  
 return mBinder.asBinder();  
 }  
 private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {  
 @Override  
 public int getPid() throws RemoteException {  
 return 0;  
 }  
 @Override  
 public void basicTypes(int anInt, long aLong, boolean aBoolean,  
 float aFloat, double aDouble, String aString)  
 throws RemoteException {  
 }  
 };  
 }  

Step 3) ServiceConnection class allow to create connection between IRemoteService and your service class. So bind your service inside your activity. Change your main activity code to as follows

 import android.app.Activity;  
 import android.content.ComponentName;  
 import android.content.Context;  
 import android.content.Intent;  
 import android.content.ServiceConnection;  
 import android.os.Bundle;  
 import android.os.IBinder;  
 public class BindAidlActivity extends Activity {  
 @Override  
 protected void onCreate(Bundle savedInstanceState) {  
 super.onCreate(savedInstanceState);  
 bindService();  
 }  
 public void bindService() {  
 Intent intent = new Intent(this, AidlService.class);  
 bindService(intent, new ConnectService(), Context.BIND_AUTO_CREATE);  
 }  
 public void stoppingService() {  
 Intent intent = new Intent(this, AidlService.class);  
 stopService(intent);  
 }  
 IRemoteService uAidlService;  
 public class ConnectService implements ServiceConnection {  
 @Override  
 public void onServiceConnected(ComponentName name, IBinder service) {  
 uAidlService = IRemoteService.Stub.asInterface(service);  
 }  
 @Override  
 public void onServiceDisconnected(ComponentName name) {  
 /**  
 * Called when service disconnected  
 */  
 }  
 }  
 }  

Download All Service Binding Example

Wednesday, 20 February 2013

Binding service using Messenger in android

Binding service using Messanger is another way. Here we discussed bounding service using iBinder. This current post address the issue of bounding service using Messanger
When to use Messanger Approach
If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

Create one Class and extend Service. Register this inside android manifest.
Not make necessary changes to your service class. Create one handler class for Messanger. Handler class will handle communication with Activity.

 import android.app.Service;  
 import android.content.Intent;  
 import android.os.Handler;  
 import android.os.IBinder;  
 import android.os.Message;  
 import android.os.Messenger;  
 import android.widget.Toast;  
 public class UsingMessanger extends Service {  
 final public static int Msg = 1;  
 @Override  
 public void onCreate() {  
 super.onCreate();  
 }  
 @Override  
 public IBinder onBind(Intent arg0) {  
 Messenger mssMessenger = new Messenger(new HandlerMessag());  
 return mssMessenger.getBinder();  
 }  
 public class HandlerMessag extends Handler {  
 @Override  
 public void handleMessage(Message msg) {  
 switch (msg.what) {  
 case Msg:  
 Toast.makeText(getApplicationContext(), "Service: I got your message",  
 Toast.LENGTH_SHORT).show();  
 break;  
 default:  
 super.handleMessage(msg);  
 }  
 }  
 }  
 }  
Now change the activity to handle Service connection.
 import android.app.Activity;  
 import android.content.ComponentName;  
 import android.content.Context;  
 import android.content.Intent;  
 import android.content.ServiceConnection;  
 import android.os.Bundle;  
 import android.os.IBinder;  
 import android.os.Message;  
 import android.os.Messenger;  
 import android.os.RemoteException;  
 public class MessangerActivity extends Activity {  
 Messenger messenger;  
 @Override  
 protected void onCreate(Bundle savedInstanceState) {  
 super.onCreate(savedInstanceState);  
 bindService();  
 }  
 public void bindService() {  
 Intent intent = new Intent(this, UsingMessanger.class);  
 bindService(intent, new ConnectService(), Context.BIND_AUTO_CREATE);  
 }  
 public void stoppingService() {  
 Intent intent = new Intent(this, UsingMessanger.class);  
 stopService(intent);  
 }  
 public class ConnectService implements ServiceConnection {  
 @Override  
 public void onServiceConnected(ComponentName name, IBinder service) {  
 messenger = new Messenger(service);  
 Message msg = Message.obtain(null, UsingMessanger.Msg, 0, 0);  
 try {  
 messenger.send(msg);  
 } catch (RemoteException e) {  
 e.printStackTrace();  
 }  
 }  
 @Override  
 public void onServiceDisconnected(ComponentName name) {  
 /**  
 * Called when service disconnected  
 */  
 }  
 }  
 }  


 All Service Binding Source Code

Binding service using iBinder and updating UI in android

Binding service is used when you want to communicate with service either it for updating UI with the work you are doing in service or using values of service's current instance. See binding service using Messanger

You can bind service by multiple ways but here i explain using iBinder method.

Some Fact
You can only bind service with activity not with the BroadcastReceiver

Binding Purpose
To get current instance of Service to interact with its member
When to use iBinder Approach
If your service is private to your own application and runs in the same process as the client (which is common), you should create your interface by extending the Binder class and returning an instance of it from onBind()
Binding service automatically start service so use either bindService() or both methods. UsingiBinder is service class

public void startingService() {
Intent intent = new Intent(this, UsingiBinder.class);
startService(intent);
}

public void bindService() {
Intent intent = new Intent(this, UsingiBinder.class);
bindService(intent, new ConnectService(), 0);
}

ConnectService is ServiceConnection that provide you bridge between Service and activity. It has two method

onServiceConnected(ComponentName name, IBinder service)
onServiceDisconnected(ComponentName name)

Service class has method onBind(Intent arg0) that help to return service instance in the form of iBinder

 import android.app.Service;  
 import android.content.Intent;  
 import android.os.Binder;  
 import android.os.IBinder;  
 public class UsingiBinder extends Service {  
 @Override  
 public IBinder onBind(Intent arg0) {  
 return iBinder;  
 }  
 private IBinder iBinder = new ContainsLocal();  
 public class ContainsLocal extends Binder {  
 UsingiBinder getBinder() {  
 return UsingiBinder.this;  
 }  
 }  
 }  

Download All Service Binding Example

Saturday, 4 August 2012

Updating UI from background service in android

Its recommended that always perform long task using background Thread or Service. If you have not idea how to create basic service and Thread then please read these

Now back to some current one, we can perform any long task in background using service. Let you are downloading movies in your application and we run one service to start download. But if we did not notify about this to user then end user will think that application is not responsive. We can not  update User interface from service directly to show progress in android.

so if you are using service in your android application , two step will make sure update of user interface when ever new data loaded inside service

  •  Create one service from activity 
  • Then bind this service to activity using service connection 
Remember These some points about service 
  1. Service will not create new instance if it is already running
  2. When you bind service it will call onserviceConnected() method
  3. You can not unbind or bind service if it is already stopped (either explicitly or implicitly)
Service connection will be perform using Binder. Whenever you will bind service it will call connected method of service connection. in this method we will get Service class object, and our work done. Using object of service we can use any updated value from service class

   LocalService localservice
;
  
ServiceConnection serviceConnection = new ServiceConnection() {

      
@Override
      
PUBLIC void onServiceDisconnected(ComponentName name) {
           txt_view.setText
("DisConnected !!!!! bind it for updating UI...";
      
}

      
@Override
      
PUBLIC void onServiceConnected(ComponentName name, IBinder SERVICE) {
           localservice
= ((LocalService.LocalBinder) SERVICE).getBinder();
          
try {
               txt_view.setText
(String.valueOf(localservice.STR));
              
localservice.STR = "String changes from Activit"
           } catch
(Exception e) {
           }
       }
   }
;}


In service class we will create a Binder to return the object of current service.

   @Override
  
PUBLIC IBinder onBind(Intent intent) {
      
RETURN iBinder;
  
}

   private IBinder iBinder
= new LocalBinder();

  
PUBLIC class LocalBinder extends Binder {
       LocalService getBinder
() {
          
RETURN LocalService.this;
      
}
   }


Here onBind() will return service class object when service will connected . I have taken a string inside the service and set to TextView's background .

on calling bindservice() onserviceConnected() will call. But it onServiceDisconnected() will never call either you call unbind service or stop service. It will only call when service will stop stopped in memory low situation or by OS. once service disconnected, you will not get receive result any more

     
Service Main Screen
  This screen have only simple UI for starting , binding, unbinding and stopping service. I started the service     

   private Intent intent = NULL;
  
private OnClickListener startService = new OnClickListener() {

      
@Override
      
PUBLIC void onClick(VIEW v) {
           intent
= new Intent(MainActivity.this,      

                LocalService.class);
           startService(intent);
      
}
     }
;


It start the service. Now we will bind study how bind and unbind service

Binding Sevice....while binding service we will user ServiceConnection class object

   private OnClickListener boundService = new OnClickListener() {

      
@Override
      
PUBLIC void onClick(VIEW v) {
          
IF (intent != NULL) {
               bindService
(intent, serviceConnection, BIND_AUTO_CREATE);
          
} ELSE {
               Toast.makeText
(MainActivity.this,
                      
"First Satrt service to bind." Toast.LENGTH_LONG)
                      
.show();
          
}
       }
   }
;
  
private OnClickListener unboundService = new OnClickListener() {

      
@Override
      
PUBLIC void onClick(VIEW v) {
          
IF (intent != NULL) {
               unbindService
(serviceConnection);
              
txt_view.setText("DisConnected !!!!! bind it for updating UI...";
          
} ELSE {
               Toast.makeText
(MainActivity.this,
                      
"First Satrt bind to UnBind." Toast.LENGTH_LONG)
                      
.show();
          
}
       }
   }
;
  
private OnClickListener stopService = new OnClickListener() {

      
@Override
      
PUBLIC void onClick(VIEW v) {
          
IF (intent != NULL) {
               stopService
(intent);
          
} ELSE {
               Toast.makeText
(MainActivity.this, "First Satrt to stop it."
                       Toast.LENGTH_LONG
).show();
          
}
       }
   }
;


Now see some screen shot to get idea how this will work..

        Android trainner
        Service Disconnected After Unbind
                                     
                    Activity Showed value from Service   


Now i think you got some idea how we can update UI from background service
Download source cod to read complete piece of code

 Download All Service Binding Example                                                     

Android News and source code