Android App Continue Running in Background Xamarin Android

Introduction To Android Services

Android provides platform support to execute with and without a user interface. An Android service is defined as an application component that is generally used to perform long tasks in the background without needing user input.

Services could be used for a variety of purposes:

  • Handle network transactions
  • Play audio/music in background
  • Perform non-user input requiring I/O operations like backup
  • Periodic downloads of certain types of data

Basics of Android Services

The service isn't a separate process, nor a thread. It runs in the same process as the application. A service provides the following features of interest:

  • Something that the application can communicate to the Android system what it wants to execute in the background without telling user what it is doing
  • A mechanism for an application to expose certain functionality to other applications

A service needs to declare itself in the application manifest file (AndroidManifest.xml) as a <service>.

<manifest ... >    ...    <application ... >       <service android_name=".MyService" />       ...    </application> </manifest>        

Services can be started in one of two ways: by using Context.startService() or Context.bindService().

Good programming practices dictate to use an explicit intent when starting or binding a service. One must also not declare intent filters for a service.

How to Create a Service in Android

There are two ways to create a service. If the service is simple, you can create a subclass of IntentService and only implement the onHandleIntent() method.

To create a service in a custom manner, one needs to create a subclass of Service and override some methods (methods that handle key aspects of service lifecycle).

  • onStartCommand(): This method is called when another component requests the service to be started by calling startService().
  • onBind(): This method is called when another component wants to bind to the service by calling bindService().
  • onCreate(): This method is called when the service is first created. This method is meant for "housekeeping." The Android platform calls this method before it calls onStartCommand() or onBind().
  • onDestroy(): This method is called when the service is no longer used and is to be destroyed. All cleanup code should reside in this method.

Note that when Android system runs low on resources, background services can be destroyed to free up resources, so make sure to implement the above method properly.

Hands On with Android Services

Let us now create a simple service—"started service"—that will be started by another component by calling startService().

Fire up Android Studio and start a new Android Studio Project.

Serv01
Figure 1: Starting Android Studio

Provide ServiceDemo as the Application Name and click Next.

Serv02
Figure 2: Naming the application

On the next screen, leave the default values and click Next.

Serv03
Figure 3: Leaving the defaults in place

On the "Add an activity to Mobile" page, choose "Blank Activity". This creates an application with a single activity.

Serv04
Figure 4: Starting a blank activity

We are then prompted to customize the activity. We will leave the default values unchanged.

Serv05
Figure 5: Again, leaving the default values in place

Click Finish to creating the project files.

Next, we create a custom Service. Right-click the /src/java/ folder on the Project Explorer and select New-> Service->Service.

Serv06
Figure 6: Creating a custom Service

Leave the default values unchanged and click Finish to create the Service class.

Serv07
Figure 7: Once again, leaving the default values in place

The default code generated is as follows:

          package          com.example.vipul.servicedemo;          import          android.app.Service;          import          android.content.Intent;          import          android.os.IBinder;          import          android.util.Log;          public class          MyService          extends          Service {          public          MyService() {    }     @Override          public          IBinder onBind(Intent intent) {                      // TODO: Return the communication channel       // to the service.                    throw new          UnsupportedOperationException          ("Not yet implemented");    }  }        

We will now implement the other callbacks. We will also add logging to understand the order of the calls.

          package          com.example.vipul.servicedemo;          import          android.app.Service;          import          android.content.Intent;          import          android.os.IBinder;          import          android.util.Log;          public class          MyService          extends          Service {          public          MyService() {    }     @Override          public          IBinder onBind(Intent intent) {          //            TODO: Return the communication channel to the service.                    Log.w("MyService",            "onBind callback called");          throw new          UnsupportedOperationException("Not yet implemented");    }          @Override                      public int            onStartCommand(Intent intent,            int            flags,            int            startId) {          Log.w("MyService",            "onStartCommand callback called");                      return super.onStartCommand(intent, flags, startId);          }          @Override                      public void            onCreate() {                      super.onCreate();          Log.w("MyService",            "onCreate callback called");          }          @Override                      public void            onDestroy() {                      super.onDestroy();          Log.w("MyService",            "onDestroy callback called");          }          }        

Next, we will create a Intent service. Right-click the /src tab and select New -> Service -> IntentService

Serv08
Figure 8: Selecting a New Service

Leave the suggested name for the service unchanged and click Finish to create the class.

Serv09
Figure 9: Leaving the suggested service name unchanged

You will see that the default code that is generated by Android Studio has the following content:

          package          com.example.vipul.servicedemo;          import          android.app.IntentService;          import          android.content.Intent;          import          android.content.Context;          import          android.util.Log;          /**          * An {@link            IntentService} subclass for handling asynchronous          * task requests in a service on a separate handler thread.          *            <p/>                    *            TODO: Customize class - update intent actions, extra                                * parameters and static helper methods.                    */          public class          MyIntentService          extends          IntentService {                      // TODO: Rename actions, choose action names that describe tasks that                                // this IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS                    private static final          String                      ACTION_FOO                      =          "com.example.vipul.servicedemo.action.FOO";          private static final          String                      ACTION_BAZ                      =          "com.example.vipul.servicedemo.action.BAZ";          //            TODO: Rename parameters                    private static final          String                      EXTRA_PARAM1                      =          "com.example.vipul.servicedemo.extra.PARAM1";          private static final          String                      EXTRA_PARAM2                      =          "com.example.vipul.servicedemo.extra.PARAM2";          /**          * Starts this service to perform action Foo with the given parameters. If          * the service is already performing a task this action will be queued.          *          *            @see            IntentService          */                      //            TODO: Customize helper method                    public static void          startActionFoo(Context context, String param1,          String param2) {       Intent intent =          new          Intent(context, MyIntentService.class);       intent.setAction(            ACTION_FOO          );       intent.putExtra(            EXTRA_PARAM1          , param1);       intent.putExtra(            EXTRA_PARAM2          , param2);       context.startService(intent);    }          /**          * Starts this service to perform action Baz with the given parameters. If          * the service is already performing a task this action will be queued.          *          *            @see            IntentService          */                      //            TODO: Customize helper method                    public static void          startActionBaz(Context context, String param1,          String param2) {       Intent intent =          new          Intent(context, MyIntentService.class);       intent.setAction(            ACTION_BAZ          );       intent.putExtra(            EXTRA_PARAM1          , param1);       intent.putExtra(            EXTRA_PARAM2          , param2);       context.startService(intent);    }          public          MyIntentService() {          super("MyIntentService");    }     @Override          protected void          onHandleIntent(Intent intent) {          if          (intent !=          null) {          final          String action = intent.getAction();          if          (            ACTION_FOO          .equals(action)) {          final          String param1 = intent.getStringExtra(            EXTRA_PARAM1          );          final          String param2 = intent.getStringExtra(            EXTRA_PARAM2          );             handleActionFoo(param1, param2);          }          else if          (            ACTION_BAZ          .equals(action)) {          final          String param1 = intent.getStringExtra(            EXTRA_PARAM1          );          final          String param2 = intent.getStringExtra(            EXTRA_PARAM2          );             handleActionBaz(param1, param2);          }       }     }          /**          * Handle action Foo in the provided background thread with the          * provided parameters.          */          private void          handleActionFoo(String param1, String param2) {          //            TODO: Handle action Foo                    throw new          UnsupportedOperationException("Not yet implemented");    }          /**          * Handle action Baz in the provided background thread with the          * provided parameters.          */          private void          handleActionBaz(String param1, String param2) {          //            TODO: Handle action Baz                    throw new          UnsupportedOperationException("Not yet implemented");    } }        

We will implement the other callbacks for the service.

          package          com.example.vipul.servicedemo;          import          android.app.IntentService;          import          android.content.Intent;          import          android.content.Context;          import          android.util.Log;          /**          * An {@link            IntentService} subclass for handling asynchronous          * task requests in a service on a separate handler thread.          *            <p/>                    *            TODO: Customize class - update intent actions, extra parameters                    * and static            helper methods.                    */          public classMyIntentService          extends          IntentService {                      // TODO: Rename actions, choose action names that describe tasks                                // that this IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS                    private static final          String                      ACTION_FOO                    =          "com.example.vipul.servicedemo.action.FOO";          private static final          String                      ACTION_BAZ                      =          "com.example.vipul.servicedemo.action.BAZ";                      // TODO: Rename parameters                    private static final          String                      EXTRA_PARAM1                    =          "com.example.vipul.servicedemo.extra.PARAM1";          private static final          String                      EXTRA_PARAM2                    =          "com.example.vipul.servicedemo.extra.PARAM2";          /**          * Starts this service to perform action Foo with the given parameters. If          * the service is already performing a task this action will be queued.          *          *            @see            IntentService          */                      //            TODO: Customize helper method                    public static void          startActionFoo(Context context, String param1,          String param2) {       Intent intent =          new          Intent(context, MyIntentService.class);       intent.setAction(            ACTION_FOO          );       intent.putExtra(            EXTRA_PARAM1          , param1);       intent.putExtra(            EXTRA_PARAM2          , param2);       context.startService(intent);    }          /**          * Starts this service to perform action Baz with the given parameters. If          * the service is already performing a task this action will be queued.          *          *            @see            IntentService          */                      //            TODO: Customize helper method                    public static void          startActionBaz(Context context, String param1,          String param2) {       Intent intent =          new          Intent(context, MyIntentService.class);       intent.setAction(            ACTION_BAZ          );       intent.putExtra(            EXTRA_PARAM1          , param1);       intent.putExtra(            EXTRA_PARAM2          , param2);       context.startService(intent);    }          public          MyIntentService() {          super("MyIntentService");    }     @Override          protected void          onHandleIntent(Intent intent) {          if          (intent !=          null) {          final          String action = intent.getAction();          if          (            ACTION_FOO          .equals(action)) {          final          String param1 = intent.getStringExtra(            EXTRA_PARAM1          );          final          String param2 = intent.getStringExtra(            EXTRA_PARAM2          );             handleActionFoo(param1, param2);          }          else if          (            ACTION_BAZ          .equals(action)) {          final          String param1 = intent.getStringExtra(            EXTRA_PARAM1          );          final          String param2 = intent.getStringExtra(            EXTRA_PARAM2          );             handleActionBaz(param1, param2);          }       }    }          /**          * Handle action Foo in the provided background thread with the provided          * parameters.          */          private void          handleActionFoo(String param1, String param2) {          //            TODO: Handle action Foo                    throw new          UnsupportedOperationException("Not yet implemented");    }          /**          * Handle action Baz in the provided background thread with the provided          * parameters.          */          private void          handleActionBaz(String param1, String param2) {          //            TODO: Handle action Baz                    throw new          UnsupportedOperationException("Not yet implemented");    }          @Override                      public int            onStartCommand(Intent intent,            int            flags,            int            startId) {          Log.w("MyIntentService",            "onStartCommand callback called");                      return super.onStartCommand(intent, flags, startId);          }          @Override                      public void            onStart(Intent intent,            int            startId) {          Log.w("MyIntentService",            "onStart callback called");                      super.onStart(intent, startId);          }          @Override                      public void            onDestroy() {          Log.w("MyIntentService",            "onDestroy callback called");                      super.onDestroy();          }          }        

Finally, we will add a couple of buttons on MainActivity. When the user clicks the buttons, we will invoke the services we have created above.

<RelativeLayout xmlns_android=          "http://schemas.android.com/apk/res/android"          xmlns:tools="http://schemas.android.com/tools"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:paddingLeft="@dimen/activity_horizontal_margin"          android:paddingRight="@dimen/activity_horizontal_margin"          android:paddingTop="@dimen/activity_vertical_margin"          android:paddingBottom="@dimen/activity_vertical_margin"          tools:context=".MainActivity"          >     <TextView android_text="@string/hello_world"       android_layout_width="wrap_content"          android:layout_height="wrap_content"          android:id="@+id/textView"          />     <Button          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Start Service"          android:id="@+id/buttonStartService"          android:layout_below="@+id/textView"          android:layout_toRightOf="@+id/textView"          android:layout_toEndOf="@+id/textView"          android:layout_marginTop="62dp"          <Button          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Start Intent Service"          android:id="@+id/buttonStartIntentService"          android:layout_centerVertical="true"          android:layout_alignLeft="@+id/buttonStartService"          android:layout_alignStart="@+id/buttonStartService"          </RelativeLayout>        

We will now implement the click event handlers for the buttons:

// MainActivity.java          package          com.example.vipul.servicedemo;          import          android.app.Service;          import          android.content.Intent;          import          android.support.v7.app.ActionBarActivity;          import          android.os.Bundle;          import          android.view.Menu;          import          android.view.MenuItem;          import          android.view.View;          public class          MainActivity          extends          ActionBarActivity {     @Override          protected voidonCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);       setContentView(R.layout.              activity_main            );    }     @Override            public boolean            onCreateOptionsMenu(Menu menu) {            // Inflate the menu; this adds items to the action bar            // if it is present.            getMenuInflater().inflate(R.menu.              menu_main            , menu);            return true;    }     @Override            public boolean            onOptionsItemSelected(MenuItem item) {            // Handle action bar item clicks here. The action bar will            // automatically handle clicks on the Home/Up button, so long            // as you specify a parent activity in AndroidManifest.xml.            intid = item.getItemId();            //noinspection SimplifiableIfStatement            if            (id == R.id.              action_settings            ) {            return true;       }            return super.onOptionsItemSelected(item);    }                          public void              onButtonServiceClick(View view) {            Intent  myServiceIntent =              new              Intent(this, MyService.class);            startService(myServiceIntent);            }                          public void              onButtonIntentServiceClick(View view){            Intent  myIntentServiceIntent =              new              Intent(this, MyIntentService.class);            startService(myIntentServiceIntent);                   }            }                  

Finally, we will wire up the event handlers with the event.

// Activity_main.xml <RelativeLayout xmlns_android=          "http://schemas.android.com/apk/res/android"          xmlns:tools="http://schemas.android.com/tools"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:paddingLeft="@dimen/activity_horizontal_margin"          android:paddingRight="@dimen/activity_horizontal_margin"          android:paddingTop="@dimen/activity_vertical_margin"          android:paddingBottom="@dimen/activity_vertical_margin"          tools:context=".MainActivity"          >     <TextView android_text="@string/hello_world"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:id="@+id/textView"          />     <Button          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Start Service"          android:id="@+id/buttonStartService"          android:layout_below="@+id/textView"          android:layout_toRightOf="@+id/textView"          android:layout_toEndOf="@+id/textView"          android:layout_marginTop="62dp"                      android:onClick="onButtonServiceClick"                    />     <Button          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="Start Intent Service"          android:id="@+id/buttonStartIntentService"          android:layout_centerVertical="true"          android:layout_alignLeft="@+id/buttonStartService"          android:layout_alignStart="@+id/buttonStartService"                      android:onClick="onButtonIntentServiceClick"                    /> </RelativeLayout>        

Our application is now complete. When we run the application and click the buttons, we will see the screen as shown in Figure 10.

Serv10
Figure 10: The screen displaying two buttons

However, when we observe the logcat view with the warning filter, the content in Figure 11 appears:

Serv11
Figure 11: The logical view

You will observe the following order of callbacks being invoked.

11-22 16:50:40.823 1690-1709/com.example.vipul.servicedemo    W/EGL_emulation : eglSurfaceAttrib not implemented 11-22 16:50:40.823 1690-1709/com.example.vipul.servicedemo    W/OpenGLRenderer : Failed to set EGL_SWAP_BEHAVIOR on    surface 0xb4b48380, error=EGL_SUCCESS 11-22 16:51:08.180 1690-1690/com.example.vipul.servicedemo    W/MyService : onCreate callback called 11-22 16:51:08.183 1690-1690/com.example.vipul.servicedemo    W/MyService : onStartCommand callback called 11-22 16:51:17.123 1690-1690/com.example.vipul.servicedemo    W/MyIntentService : onStartCommand callback called 11-22 16:51:17.124 1690-1690/com.example.vipul.servicedemo    W/MyIntentService : onStart callback called 11-22 16:51:17.182 1690-1690/com.example.vipul.servicedemo    W/MyIntentService : onDestroy callback called 11-22 16:53:19.340 1690-1697/com.example.vipul.servicedemo    W/art : Suspending all threads took: 5.497ms 11-22 16:54:37.475 1690-1697/com.example.vipul.servicedemo    W/art : Suspending all threads took: 5.694ms 11-22 16:57:33.791 1690-1697/com.example.vipul.servicedemo    W/art : Suspending all threads took: 7.551ms 11-22 16:58:58.447 1690-1697/com.example.vipul.servicedemo    W/art : Suspending all threads took: 5.555ms        

This shows the event order in which service callbacks are called.

You can see that the IntentService destroy callback was destroyed in my case because I stopped app debugging.

Summary

In this article, we learned the basics about Android services and how to create a custom service and a intent service. I hope you have found this information useful. You can download the sample code from the link at the bottom of this article.

About the Author

Vipul Patel is a technology geek based in Seattle. He can be reached at [email protected] You can visit his LinkedIn profile at https://www.linkedin.com/pub/vipul-patel/6/675/508.

stipebestudy.blogspot.com

Source: https://www.developer.com/languages/xml/executing-long-running-background-tasks-in-android-apps-without-an-interface-using-services/

0 Response to "Android App Continue Running in Background Xamarin Android"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel