Android 简明教程

Android - Services

Sr.No.

State & Description

1

Started A service is started when an application component, such as an activity, starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed.

2

Bound A service is bound when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC).

服务拥有生命周期回调方法,你可实现这些回调方法来监视服务状态的变化,并可在适当的阶段执行工作。下图左侧显示了通过 startService() 来创建服务时的生命周期,右图显示了通过 bindService() 来创建服务时的生命周期:(图像由 android.com 提供)

A service has life cycle callback methods that you can implement to monitor changes in the service’s state and you can perform work at the appropriate stage. The following diagram on the left shows the life cycle when the service is created with startService() and the diagram on the right shows the life cycle when the service is created with bindService(): (image courtesy : android.com )

services

若要创建服务,可创建一个 Java 类,它扩展 Service 基类或其现有子类。 Service 基类定义了各种回调方法,其中最重要的方法如下。你无需实现所有回调方法。但是,理解每种回调方法并实现那些确保你的应用程序符合用户期望的方法非常重要。

To create an service, you create a Java class that extends the Service base class or one of its existing subclasses. The Service base class defines various callback methods and the most important are given below. You don’t need to implement all the callbacks methods. However, it’s important that you understand each one and implement those that ensure your app behaves the way users expect.

Sr.No.

Callback & Description

1

onStartCommand() The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). If you implement this method, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService() methods.

2

onBind() The system calls this method when another component wants to bind with the service by calling bindService(). If you implement this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder object. You must always implement this method, but if you don’t want to allow binding, then you should return null.

3

onUnbind() The system calls this method when all clients have disconnected from a particular interface published by the service.

4

onRebind() The system calls this method when new clients have connected to the service, after it had previously been notified that all had disconnected in its onUnbind(Intent).

5

onCreate() The system calls this method when the service is first created using onStartCommand() or onBind(). This call is required to perform one-time set-up.

6

onDestroy() The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc.

以下框架服务演示了每个生命周期方法 −

The following skeleton service demonstrates each of the life cycle methods −

package com.tutorialspoint;

import android.app.Service;
import android.os.IBinder;
import android.content.Intent;
import android.os.Bundle;

public class HelloService extends Service {

   /** indicates how to behave if the service is killed */
   int mStartMode;

   /** interface for clients that bind */
   IBinder mBinder;

   /** indicates whether onRebind should be used */
   boolean mAllowRebind;

   /** Called when the service is being created. */
   @Override
   public void onCreate() {

   }

   /** The service is starting, due to a call to startService() */
   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      return mStartMode;
   }

   /** A client is binding to the service with bindService() */
   @Override
   public IBinder onBind(Intent intent) {
      return mBinder;
   }

   /** Called when all clients have unbound with unbindService() */
   @Override
   public boolean onUnbind(Intent intent) {
      return mAllowRebind;
   }

   /** Called when a client is binding to the service with bindService()*/
   @Override
   public void onRebind(Intent intent) {

   }

   /** Called when The service is no longer used and is being destroyed */
   @Override
   public void onDestroy() {

   }
}

Example

此示例将通过简单的步骤向你展示如何创建你自己的 Android 服务。按照以下步骤修改我们在 Hello World 示例一章中创建的 Android 应用程序 −

This example will take you through simple steps to show how to create your own Android Service. Follow the following steps to modify the Android application we created in Hello World Example chapter −

Step

Description

1

You will use Android StudioIDE to create an Android application and name it as My Application under a package com.example.tutorialspoint7.myapplication as explained in the Hello World Example chapter.

2

Modify main activity file MainActivity.java to add startService() and stopService() methods.

3

Create a new java file MyService.java under the package com.example.My Application. This file will have implementation of Android service related methods.

4

Define your service in AndroidManifest.xml file using <service…​/> tag. An application can have one or more services without any restrictions.

5

Modify the default content of res/layout/activity_main.xml file to include two buttons in linear layout.

6

No need to change any constants in res/values/strings.xml file. Android studio take care of string values

7

Run the application to launch Android emulator and verify the result of the changes done in the application.

下面是修改后的主活动文件 MainActivity.java 的内容。此文件可包括每个基本生命周期方法。我们已添加了 startService() 和 stopService() 方法来启动和停止服务。

Following is the content of the modified main activity file MainActivity.java. This file can include each of the fundamental life cycle methods. We have added startService() and stopService() methods to start and stop the service.

package com.example.tutorialspoint7.myapplication;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {
   String msg = "Android : ";

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Log.d(msg, "The onCreate() event");
   }

   public void startService(View view) {
      startService(new Intent(getBaseContext(), MyService.class));
   }

   // Method to stop the service
   public void stopService(View view) {
      stopService(new Intent(getBaseContext(), MyService.class));
   }
}

下面是 MyService.java 的内容。此文件可根据要求实现与基于服务的相关的一个或多个方法。目前我们仅实现两种方法 onStartCommand() 和 onDestroy() −

Following is the content of MyService.java. This file can have implementation of one or more methods associated with Service based on requirements. For now we are going to implement only two methods onStartCommand() and onDestroy() −

package com.example.tutorialspoint7.myapplication;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

/**
   * Created by TutorialsPoint7 on 8/23/2016.
*/

public class MyService extends Service {
   @Nullable
   @Override
   public IBinder onBind(Intent intent) {
      return null;
   }

   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      // Let it continue running until it is stopped.
      Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
      return START_STICKY;
   }

   @Override
   public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
   }
}

以下是修改后的 AndroidManifest.xml 文件的内容。我们在此处添加了 <service…​/> 标记以包含我们的服务 −

Following will the modified content of AndroidManifest.xml file. Here we have added <service…​/> tag to include our service −

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.tutorialspoint7.myapplication">

   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">

      <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>

以下是 res/layout/activity_main.xml 文件的内容,用于包含两个按钮 −

Following will be the content of res/layout/activity_main.xml file to include two buttons −

<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:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Example of services"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />

   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point "
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_above="@+id/imageButton"
      android:layout_centerHorizontal="true"
      android:layout_marginBottom="40dp" />

   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_centerVertical="true"
      android:layout_centerHorizontal="true" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/button2"
      android:text="Start Services"
      android:onClick="startService"
      android:layout_below="@+id/imageButton"
      android:layout_centerHorizontal="true" />

   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Stop Services"
      android:id="@+id/button"
      android:onClick="stopService"
      android:layout_below="@+id/button2"
      android:layout_alignLeft="@+id/button2"
      android:layout_alignStart="@+id/button2"
      android:layout_alignRight="@+id/button2"
      android:layout_alignEnd="@+id/button2" />

</RelativeLayout>

让我们尝试运行我们刚刚修改过的 Hello World! 应用程序。我假设你在进行环境设置时已创建了 AVD 。要从 Android Studio 运行该应用程序,请打开项目的一个活动文件,然后单击工具栏中的运行图标。Android Studio 会将该应用程序安装到你的 AVD 并启动它,如果你的设置和应用程序一切正常,它将显示以下模拟器窗口 −

Let’s try to run our modified Hello World! application we just modified. I assume you had created your AVD while doing environment setup. To run the app from Android studio, open one of your project’s activity files and click Run icon from the tool bar. Android Studio installs the app on your AVD and starts it and if everything is fine with your set-up and application, it will display following Emulator window −

services1

现在要启动你的服务,让我们单击 Start Service 按钮,这将启动服务,并且根据我们在 onStartCommand() 方法中编程,一条消息服务已启动将显示在模拟器的底部,如下所示 −

Now to start your service, let’s click on Start Service button, this will start the service and as per our programming in onStartCommand() method, a message Service Started will appear on the bottom of the the simulator as follows −

services2

要停止服务,你可以单击停止服务按钮。

To stop the service, you can click the Stop Service button.