Android服务


一个 service 是在执行长时间运行的操作,而无需与用户交互的后台运行一个组件,它的工作原理,即使应用程序被破坏。服务基本上可以采取两种状态 -

序号 状态和描述
1

Started

服务被启动时的应用程序组件,如一个活动,通过调用启动它startService() 一旦启动,服务可以无限期地在后台运行,即使启动它的组件被销毁。

2

Bound

当应用程序组件通过调用bindService()绑定到服务时绑定服务绑定服务提供客户端 - 服务器接口,允许组件与服务交互,发送请求,获取结果,甚至跨进程通信(IPC)进程。

服务具有生命周期回调方法,您可以实施这些方法来监视服务状态的变化,并且可以在适当的阶段执行工作。左侧的下图显示了使用startService()创建服务时的生命周期,右侧的图显示了使用bindService()创建服务时的生命周期:( 图片提供:android.com)

Android服务生命周期

要创建服务,请创建一个扩展Service基类或其现有子类的Java类。该 服务 基类定义的各种回调方法和最重要的如下。您不需要实现所有回调方法。但是,了解每一个并实施确保您的应用程序符合用户期望的行为非常重要。

序号 回调和说明
1

onStartCommand()

当另一个组件(如活动通过调用startService()请求启动服务时,系统会调用此方法如果实现此方法,则通过调用stopSelf()stopService()方法,您有责任在完成工作时停止服务

2

onBind()

当另一个组件想要通过调用bindService()与服务绑定时,系统调用此方法如果实现此方法,则必须通过返回IBinder对象来提供客户端用于与服务通信的接口您必须始终实现此方法,但如果您不想允许绑定,则应返回null

3

onUnbind()

当所有客户端与服务发布的特定接口断开连接时,系统将调用此方法。

4

onRebind()

系统在新客户端连接到服务之后调用此方法,之前已通知其所有已在其onUnbind(Intent)中断开连接

5

onCreate()

首次使用onStartCommand()onBind()创建服务时,系统会调用此方法需要此调用才能执行一次性设置。

6

onDestroy()

当服务不再使用并被销毁时,系统会调用此方法。您的服务应该实现此操作以清理任何资源,如线程,注册的侦听器,接收器等。

以下骨架服务演示了每种生命周期方法

package com.codingdict;

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() {

   }
}

此示例将向您介绍如何创建自己的Android服务的简单步骤。按照以下步骤修改我们在 Hello World示例 章节中创建的Android应用程序-

Step Description
1 您将使用Android StudioIDE创建一个Android应用程序,并com.example.codingdict7.myapplication包下将其命名为My ApplicationHello World示例章节中所述。
2 修改主活动文件MainActivity.java以添加startService()stopService()方法。
3 在包com.example.My Application创建一个新的java文件MyService.java该文件将实现与Android服务相关的方法。
4 使用<service ... />标记AndroidManifest.xml文件中定义您的服务应用程序可以没有任何限制地拥有一个或多个服务。
5 修改res / layout / activity_main.xml文件的默认内容以包括线性布局中的两个按钮。
6 无需更改res / values / strings.xml文件中的任何常量Android studio负责字符串值
7 运行应用程序以启动Android模拟器并验证应用程序中所做更改的结果。

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

package com.example.codingdict7.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 的内容。此文件可以根据需要实现与Service关联的一个或多个方法。目前我们只在 onStartCommand()onDestroy() 上实现两种方法-

package com.example.codingdict7.myapplication;

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

/**
   * Created by codingdict7 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 ... />标签以包含我们的服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.codingdict7.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 文件的内容,包括两个按钮

<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工作室运行应用程序,请打开项目的某个活动文件,然后单击Android StudioRun图标工具栏中的“运行” 图标。Android Studio在您的AVD上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示以下模拟器窗口

Android服务演示

现在开始你的服务,让我们点击 开始服务 按钮,这将启动服务,根据我们在 onStartCommand() 方法中的编程, 服务开始 的消息将显示在模拟器的底部,如下所示 -

Android服务启动

要停止该服务,可以单击“停止服务”按钮。