【Android】安卓学习笔记之服务的基本用法

来源:互联网 发布:淘宝上架话费充值 编辑:程序博客网 时间:2024/06/10 03:21

1、定义一个服务

新增一个名为MyService 的类,并让它继承自Servic:

public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();}}

      可以看到,这里我们又重写了onCreate()、onStartCommand()和onDestroy()这三个方法,它们是每个服务中最常用到的三个方法了。其中onCreate()方法会在服务创建的时候调用,onStartCommand()方法会在每次服务启动的时候调用,onDestroy()方法会在服务销毁的时候调用。
      通常情况下,如果我们希望服务一旦启动就立刻去执行某个动作,就可以将逻辑写在onStartCommand()方法里。而当服务销毁时,我们又应该在onDestroy()方法中去回收那些不再使用的资源。
      另外需要注意,每一个服务都需要在AndroidManifest.xml 文件中进行注册才能生效,不知道你有没有发现,这是Android 四大组件共有的特点。于是我们还应该修改AndroidManifest.xml文件,代码如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.servicetest"    android:versionCode="1"    android:versionName="1.0" >……    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >……        <service android:name=".MyService" >        </service>    </application></manifest>
这样的话,就已经将一个服务完全定义好了。


2、启动和停止服务

这里我们在布局文件中加入了两个按钮,分别是用于启动服务和停止服务的。

然后修改MainActivity 中的代码,如下所示:

public class MainActivity extends Activity implements OnClickListener {private Button startService;private Button stopService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);startService = (Button) findViewById(R.id.start_service);stopService = (Button) findViewById(R.id.stop_service);startService.setOnClickListener(this);stopService.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.start_service:Intent startIntent = new Intent(this, MyService.class);startService(startIntent); // 启动服务break;case R.id.stop_service:Intent stopIntent = new Intent(this, MyService.class);stopService(stopIntent); // 停止服务break;default:break;}}}

      可以看到,这里在onCreate()方法中分别获取到了Start Service 按钮和Stop Service 按钮的实例,并给它们注册了点击事件。然后在Start Service 按钮的点击事件里,我们构建出了一个Intent 对象,并调用startService()方法来启动MyService 这个服务。在Stop Serivce 按钮的点击事件里,我们同样构建出了一个Intent 对象,并调用stopService()方法来停止MyService这个服务。startService()和stopService()方法都是定义在Context 类中的,所以我们在活动里可以直接调用这两个方法。注意,这里完全是由活动来决定服务何时停止的,如果没有点击Stop Service 按钮,服务就会一直处于运行状态。那服务有没有什么办法让自已停止下来呢?当然可以,只需要在MyService 的任何一个位置调用stopSelf()方法就能让这个服务停止下来了。


3、活动和服务进行通信

      有没有什么办法能让活动和服务的关系更紧密一些呢?例如在活动中指挥服务去干什么,服务就去干什么。当然可以,这就需要借助我们刚刚忽略的onBind()方法了。
比如说目前我们希望在MyService 里提供一个下载功能,然后在活动中可以决定何时开始下载,以及随时查看下载进度。实现这个功能的思路是创建一个专门的Binder 对象来对下载功能进行管理,修改MyService 中的代码,如下所示:
public class MyService extends Service {private DownloadBinder mBinder = new DownloadBinder();class DownloadBinder extends Binder {public void startDownload() {Log.d("MyService", "startDownload executed");}public int getProgress() {Log.d("MyService", "getProgress executed");return 0;}}@Overridepublic IBinder onBind(Intent intent) {return mBinder;}.....}
      可以看到,这里我们新建了一个DownloadBinder 类,并让它继承自Binder,然后在它的内部提供了开始下载以及查看下载进度的方法。当然这只是两个模拟方法,并没有实现真正的功能,我们在这两个方法中分别打印了一行日志。
      接着,在MyService 中创建了DownloadBinder 的实例,然后在onBind()方法里返回了这个实例,这样MyService 中的工作就全部完成了。
      下面就要看一看,在活动中如何去调用服务里的这些方法了。首先需要在布局文件里新增两个按钮,这两个按钮分别是用于绑定服务和取消绑定服务的,那到底谁需要去和服务绑定呢?当然就是活动了。当一个活动和服务绑定了之后,就可以调用该服务里的Binder 提供的方法了。
修改MainActivity 中的代码,如下所示:
public class MainActivity extends Activity implements OnClickListener {private Button startService;private Button stopService;private Button bindService;private Button unbindService;private MyService.DownloadBinder downloadBinder;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {downloadBinder = (MyService.DownloadBinder) service;downloadBinder.startDownload();downloadBinder.getProgress();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);……bindService = (Button) findViewById(R.id.bind_service);unbindService = (Button) findViewById(R.id.unbind_service);bindService.setOnClickListener(this);unbindService.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {……case R.id.bind_service:Intent bindIntent = new Intent(this, MyService.class);bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务break;case R.id.unbind_service:unbindService(connection); // 解绑服务break;default:break;}}}
      可以看到,这里我们首先创建了一个ServiceConnection 的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在活动与服务成功绑定以及解除绑定的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了DownloadBinder 的实例,有了这个实例,活动和服务之间的关系就变得非常紧密了。
      现在我们可以在活动中根据具体的场景来调用DownloadBinder 中的任何public 方法,即实现了指挥服务干什么,服务就去干什么的功能。这里仍然只是做了个简单的测试,在onServiceConnected()方法中调用了DownloadBinder 的startDownload()和getProgress()方法。
      当然,现在活动和服务其实还没进行绑定呢,这个功能是在Bind Service 按钮的点击事件里完成的。可以看到,这里我们仍然是构建出了一个Intent 对象,然后调用bindService()方法将MainActivity 和MyService 进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent 对象,第二个参数是前面创建出的ServiceConnection 的实例,第三个参数则是一个标志位,这里传入BIND_AUTO_CREATE 表示在活动和服务进行绑定后自动创建服务。这会使得MyService 中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
      然后如果我们想解除活动和服务之间的绑定该怎么办呢?调用一下unbindService()方法就可以了,这也是Unbind Service 按钮的点击事件里实现的功能。

0 0