这两天在回顾Android Service方面的知识,趁着记忆没有消退之前,来总结一下。本文主要讲解Service的基本概念与使用、跨进程调用Service、系统常见Service的使用。所以本文的难度微乎其微,仅适用于想回顾Service知识点的同学,或者还不怎么了解Service的同学,至于Service源码之类的东东,等老夫分析研究之后再来分享。
一、Service基础
我相信只要接触过Android开发的人,都或多或少的了解过Service。Service是什么呢?Service是Android四大组件中与Activity最相似的组件,它完全具有自己的生命周期,不过它可没有和Activity一样的华丽外表,它常年在后台默默付出。Service也是可执行的程序,前面说了它有自己的生命周期,其创建于配置过程与Activity极其相似。不仅如此,Activity与Service还有共同的父亲Context,因此它们都可以调用Context里定义的如getResources()、getContentResolver()等方法。
1、Service的简单使用:
开发Service需要两个步骤:(1)定义一个继承Service的子类。(2)在AndroidManifest.xml文件中配置该Service。
在动手开发第一个Service之前,我们先来了解一下Service的系列生命周期方法:
(1)IBinder onBind(Intent intent):该方法是Service子类必须实现的方法。该方法返回一个IBinder对象,应用程序可通过该对象与Service组件通信。
(2)void onCreate():当该Service第一次被创建后将立即回调该方法。
(3)void onDestroy():当该Service被关闭之前将会回调该方法。
(4)void onStartCommand(Intent intent,int flags,int startId):该方法的早期版本是void onStart(Intent intent,int startId),每次客户端调用startService(Intent)方法启动该Service 时都会回调该方法。
(5)boolean onUnbind(Intent intent):当该Service上绑定的所有客户端都断开连接时将会回调该方法。
下面我们来开发我们的第一个Service,代码如下:
package com.gc.servicetest;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
/**
* 注意: onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,
* 不管怎样调用startService方法,onCreate()方法都不会再执行。
* @author Android将军
*
*/
public class MyService extends Service{
public static final String TAG=MyService.class.getSimpleName();
//必须要实现的方法
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG, "onBind() executed");
return null;
}
//Service被创建时回调该方法
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "onCreate() executed");
Log.v(TAG, "MyService thread id is "+Thread.currentThread().getId());
}
//Service被启动时回调该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
//Service被关闭之前回调该方法
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.v(TAG, "onDestroy() executed");
}
}
上面这个Service什么也没干——它只是重写了Service组件的onCreate()、onStartCommand()、onDestroy()、onBind()等方法。如果希望Service组件做某些事情,那么只要在onCreate()或onStartCommand()方法中定义相关业务代码即可。开发Service的两个步骤,我们现在已经走完了第一个步骤,下面我们一起走第二步吧。第二步很简单,在AndroidManifest.xml配置Service与在该文件中配置Activity是一样的,只不过标签一个是
当两个步骤走完,我们已经开发出了一个Service组件,接下来就可在程序中运行该Service了,Android系统中运行Service有两种方式,如下:
下面我们就来看看如何使用这两种方式来启动我们刚刚开发的Myservice,我们使用Activity作为Service的访问者,该Activity的界面中包含四个按钮,由于代码简单,这里就不再给出其布局文件,下面直接看一下MainActivity的代码,如下
package com.gc.servicetest;
import com.gc.servicetest.MyService.MyBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
*
* @author Android将军
*
*/
public class MainActivity extends Activity implements OnClickListener {
public static final String TAG=MainActivity.class.getSimpleName();
private Button mBtnStartService;
private Button mBtnStopService;
private Button mBtnBindService;
private Button mBtnUnBindService;
private MyService.MyBinder myBinder;
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.v(TAG, "onServiceDisconnected() executed");
Log.v(TAG, "onServiceDisconnected() executed name"+name);
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.v(TAG, "onServiceConnected() executed");
Log.v(TAG, "onServiceConnected() executed name"+name);
myBinder=(MyBinder) service;
myBinder.startDownload();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
setListener();
Log.v(TAG, "MainActivity thread id is "+Thread.currentThread().getId());
}
public void initUI()
{
mBtnStartService=(Button) findViewById(R.id.start_service);
mBtnStopService=(Button) findViewById(R.id.stop_service);
mBtnBindService=(Button) findViewById(R.id.bind_service);
mBtnUnBindService=(Button) findViewById(R.id.unbind_service);
}
public void setListener()
{
mBtnStartService.setOnClickListener(this);
mBtnStopService.setOnClickListener(this);
mBtnBindService.setOnClickListener(this);
mBtnUnBindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.start_service:
Intent mStartIntent=new Intent(this, MyService.class);
startService(mStartIntent);
break;
case R.id.stop_service:
Intent mStopIntent=new Intent(this, MyService.class);
stopService(mStopIntent);
break;
case R.id.bind_service:
Intent mBindIntent=new Intent(this, MyService.class);
bindService(mBindIntent, connection, BIND_AUTO_CREATE);
break;
case R.id.unbind_service:
unbindService(connection);
break;
default:
break;
}
}
}
到此为止,我们已经写好了一个带有Service功能的程序。然后我们运行程序,点击Start Service按钮,然后点击Stop Service按钮,可以看到如下打印结果:
如果在不关闭Service的情况下,连续点击三次Start Sevice 按钮,程序将会连续三次启动Service,打印信息如下:
从上述两种不同的操作以及打印信息,我们验证了前面MyService注释部分注意的内容的正确性,如下:
onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了, 不管怎样调用startService方法,onCreate()方法都不会再执行。
现在我们已经了解了第一种方式,那么我接下来看看第二种方式:public class MyService extends Service{
public static final String TAG=MyService.class.getSimpleName();
private MyBinder mBinder=new MyBinder();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG, "onBind() executed");
return mBinder;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "onCreate() executed");
Log.v(TAG, "MyService thread id is "+Thread.currentThread().getId());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.v(TAG, "onDestroy() executed");
}
class MyBinder extends Binder
{
public void startDownload()
{
Log.v(TAG, "startDownload() executed");
}
}
}
在进行操作之前,我们先了解一下bindService方法:
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
这里解释一下该方法的三个参数:
conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调该ServiceConnecttion对象的onServiceConnected(ComponentName name,IBinder service)方法;当Service所在的宿主进程由于异常终止或由于其他原因终止,导致该Service与访问者之间断开连接时回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。
注意:当调用者主动通过unBindService()方法断开与Service的连接时,ServiceConnection对象的onServiceDisconnected(ComponentName name)方法并不会被调用。
flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定为0(不自动创建)或BIND_AUTO_CREATE(自动创建)。
注意到ServiceConnection对象的onServiceConnected方法中有一个IBinder对象,该对象即可实现与被绑定Service之间的通信。
额,啰嗦了这么多,是不是有点晕了,咱们看看第二种方式启动MyService的执行效果吧,运行程序,点击Bind Service,然后点击unBind Service,打印信息如下:
通过上图我们可以看到,MainActivity已经成功的和MyService进行了通信。我们在MainActivity的成员对象connection的onServiceConnected的方法中调用了startDownload()方法。
下面我们来总结一下:
开发Service需要两个步骤:(1)定义一个继承Service的子类。(2)在AndroidManifest.xml文件中配置该Service。
启动Service有两种方式:(1)startService方法(2)bindService方法
通过startService方式启动Service,Service与访问者之间的基本上没有太大的关联。通过bindService方式启动Service,可以实现Service与访问者之间的通信。那么当通过bindService启动Service时,是如何进行通信的呢?我们按照本案例分析一下,当我们开发MyService类时,我们必须实现的方法是IBinder onBinder(Intent intent),当我们通过bindService方法启动MyService时,我们已经把MainActivity与MyService绑定在一起了,这时MyService方法的onBind方法所返回的IBinder对象将会传给MainActivity的成员connection里的onServiceConnected(ComponentName name,IBinder service)方法的service参数,这样MainActivity就可通过该IBinder对象与MyService进行通信了。
细心的通信会发现,通过startService启动Service时,调用了onStartCommand方法,而通过bindService方法启动Service时,并没有调用onStartCommand方法,这是为什呢?这是因为两种方式启动Service,导致Service的生命周期略有不同。在下一篇的Service的生命周期中,我会讲述清楚。
好了,BB了这么多,我想对于Service的基础知识应该差不多了,我会在文章末尾提供该Demo的下载地址,如果对你有帮助可以稍微顶一下奥,如果文中有哪里不正确,欢迎指出,如果还有疑问之处,或者我没有阐述清楚的地方,请留言指出,谢谢。
Demo:http://download.csdn.net/detail/gc_gongchao/8657063
转载请注明出处:http://blog.csdn.net/android_jiangjun/article/details/45458063