6.1.1 服务
当应用程序不再位于前台且没有正在使用它的活动时,为了确保音频继续播放,我们需要创建一个服务。服务是Android应用程序的一个组件,其用于后台运行任务,而无需与任何用户交互。
1.本地服务与远程服务
Android中存在几个可用的不同服务类。第一个将要探讨的服务称为本地服务(Local Service)。本地服务作为特定应用程序的一部分存在,而且只能够通过该应用程序访问和控制。远程服务(Remote Service)是另一种类型的服务,他们可以与其他应用程序进行通讯,由其他应用程序访问和控制。如前所述,我们将重点介绍使用一个本地服务提供音频播放功能。开发远程服务是一个非常庞大的主题,但是超出了本书的涵盖范围。
2.简单的本地服务
为了演示一个服务,让我们看看下面这个非常简单的示例。
首先需要一个活动,其带有一个允许启动和停止服务的接口。
1 package com.nthm.androidtestActivity; 2 3 import com.nthm.androidtest.R; 4 import com.nthm.androidtestService.SimpleServiceService; 5 import android.app.Activity; 6 import android.content.Intent; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 12 public class SimpleServiceActivity extends Activity implements OnClickListener {
该活动将有两个按钮——一个用于启动服务,另一个用于停止服务。
1 private Button startServiceButton; 2 private Button stopServiceButton;
为了启动和停止服务,可以使用一个标准的意图。
1 private Intent serviceIntent; 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 setContentView(R.layout.simpleserviceactivity);
该活动实现了OnClickListener,所以把每个按钮的OnClickListener都设置为“this”。
1 startServiceButton=(Button) findViewById(R.id.StartServiceButton); 2 stopServiceButton=(Button) findViewById(R.id.StopServiceButton); 3 startServiceButton.setOnClickListener(this); 4 stopServiceButton.setOnClickListener(this);
当实例化用来启动好而停止服务的意图时,可以传入作为上下文的活动,后跟该服务类。
1 serviceIntent=new Intent(this, SimpleServiceService.class); 2 } 3 4 @Override 5 public void onClick(View v) { 6 if(v==startServiceButton){
当单击startServiceButton时调用startService方法,传入刚刚创建的意图以引用服务。startService方法是Context类的一部分,而活动时Context的一个子类。
1 startService(serviceIntent); 2 }else if(v==stopServiceButton){
当单击stopServiceButton时调用stopService方法,传入引用该服务的相同意图。与startService方法一样,stopService方法也是Context类的一部分。
1 stopService(serviceIntent); 2 } 3 } 4 }
下面是simpleserviceactivity.xml文件,其定义了用于上述活动的布局。该布局包含startService和stopService按钮以及一个TextView对象。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <TextView 7 android:text="Simple Service" 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content"></TextView> 10 <Button 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:id="@+id/StartServiceButton" 14 android:text="Start Button"/> 15 <Button 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:id="@+id/StopServiceButton" 19 android:text="Stop Button"/> 20 </LinearLayout>
现在可以继续完成该服务本身的代码。在这个示例中的服务不做任何事情,只是使用Toast告诉我们何时已经启动和停止。
1 package com.nthm.androidtestService; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.IBinder; 6 import android.util.Log;
该服务类扩展android.app.Service类。该服务是抽象类,所以为了扩展他,必须至少实现onBind方法。在这个非常简单的示例中,我们将不会“绑定”到服务。因此,将仅仅在onBind方法中返回null。
1 public class SimpleServiceService extends Service { 2 3 @Override 4 public IBinder onBind(Intent intent) { 5 return null; 6 }
后续的3个方法表示了服务的生命周期。与活动中一样,当实例化服务时会调用onCreate方法。它将使被调用的第一个方法。
1 @Override 2 public void onCreate() { 3 super.onCreate(); 4 Log.v("SIMPLESERVICE", "onCreate"); 5 }
每当利用一个匹配服务的意图调用startService时,将会调用onStartCommand方法,因此可能会多次调用它。onStartCommand方法将返回一个整数值,其表示如果结束该服务,那么操作系统应该如何执行操作。在这里使用的START_STICKY表明如果结束服务,那么将重新启动该服务。
1 @Override 2 public int onStartCommand(Intent intent, int flags, int startId) { 3 Log.v("SIMPLESERVICE", "onStartCommand"); 4 //return super.onStartCommand(intent, flags, startId); 5 return START_STICKY; 6 }
当操作系统销毁一个服务时调用onDestory方法。在这个示例中,当活动调用stopService方法时触发该方法。该方法用于在关闭服务时完成所有必需的清理工作。
1 @Override 2 public void onDestroy() { 3 Log.v("SIMPLESERVICE", "onDestroy"); 4 super.onDestroy(); 5 } 6 }
最后,为了使此示例能够工作,需要在清单文件中添加一个条目,其指定了该服务。
1 <service android:name=".SimpleServiceService"/>
当然,除了输出到日志以指示服务何时已经启动或停止之外,这个示例不做任何其他事情。接下来我们将继续深入,使得服务能够实际做些事情。
posted on 2014-08-28 15:11 宁静致远,一览众山小 阅读(171) 评论(0) 编辑 收藏 举报