Android Service

来源:互联网 发布:淘宝店铺自己做活动 编辑:程序博客网 时间:2024/06/08 09:04

简介:

1. 基础知识

  • 定义:服务,属于Android中的四大之一组件
  • 作用:提供需要在后台长期运行的服务(如复杂计算、下载等等)(运行在主线程需要耗时操作得启用子线程
  • 特点:长生命周期的、没有用户界面、在后台运行

2. 生命周期方法详解


目录


目录

生命周期表:


1. 生命周期常用方法

在Service的生命周期里,常用的有:

  • 4个手动调用的方法
手动调用方法作用startService()启动服务stopService()关闭服务bindService()绑定服务unbindService()解绑服务
  • 5个内部自动调用的方法
内部自动调用的方法作用onCreat()创建服务onStartCommand()开始服务onDestroy()销毁服务onBind()绑定服务onUnbind()解绑服务

2. 生命周期方法具体介绍

主要介绍内部调用方法和外部调用方法的关系。

2.1 startService()

  • 作用:启动Service服务
  • 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
  • 调用逻辑如下:

    调用逻辑

2.2 stopService()

  • 作用:关闭Service服务
  • 手动调用stopService()后,自动调用内部方法:onDestory()
  • 调用的逻辑:
调用逻辑

2.3 bindService()

  • 作用:绑定Service服务
  • 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
  • 调用的逻辑:

调用的逻辑

2.4 unbindService()

  • 作用:解绑Service服务
  • 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
  • 调用的逻辑:

    调用的逻辑

3. 常见的生命周期使用

3.1 只使用startService启动服务的生命周期


startService启动服务的生命周期

3.2 只使用BindService绑定服务的生命周期


BindService绑定服务的生命周期

3.3 同时使用startService()启动服务、BindService()绑定服务的生命周期


Paste_Image.png

3.4 特别注意

  • startService()和stopService()只能开启和关闭Service,无法操作Service;

    bindService()和unbindService()可以操作Service

  • startService开启的Service,调用者退出后Service仍然存在;(跟Acitivity的关系不密切,即时界面销毁服务还在
  • BindService开启的Service,调用者退出后,Service随着调用者销毁。(跟Activity关系密切,界面销毁,服务也会销毁。)
  • StartService 和BindService 结合使用时:先StartService 启动服务,再BindService (不会调用oncreat只调用onBind())绑定服务。关闭界面,Service不会关闭,只后会解绑。不会调用ondestory()方法,只会调用onUnbind(),再次进入界面,先StartService ,BindService。不会创建新的服务。不会调用onCreate()),只会调用onstartcommand()及onBind()。想真正解除服务只能先stopService()再unbindService()一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。
eg:

如下所示:

[java] view plain copy
  1. public class MyService extends Service {  
  2.   
  3.     public static final String TAG = "MyService";  
  4.   
  5.     private MyBinder mBinder = new MyBinder();  
  6.   
  7.     @Override  
  8.     public void onCreate() {  
  9.         super.onCreate();  
  10.         Log.d(TAG, "onCreate() executed");  
  11.     }  
  12.   
  13.     @Override  
  14.     public int onStartCommand(Intent intent, int flags, int startId) {  
  15.         Log.d(TAG, "onStartCommand() executed");  
  16.         return super.onStartCommand(intent, flags, startId);  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onDestroy() {  
  21.         super.onDestroy();  
  22.         Log.d(TAG, "onDestroy() executed");  
  23.     }  
  24.   
  25.     @Override  
  26.     public IBinder onBind(Intent intent) {  
  27.         return mBinder;  
  28.     }  
  29.   
  30.     class MyBinder extends Binder {  
  31.   
  32.         public void startDownload() {  
  33.             Log.d("TAG""startDownload() executed");  
  34.             // 执行具体的下载任务  
  35.         }  
  36.   
  37.     }  
  38.   
  39. }  

这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。

项目中的每一个Service都必须在AndroidManifest.xml中注册才行

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="com.example.servicetest"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0" >  
  5.   
  6.     <uses-sdk  
  7.         android:minSdkVersion="14"  
  8.         android:targetSdkVersion="17" />  
  9.   
  10.     <application  
  11.         android:allowBackup="true"  
  12.         android:icon="@drawable/ic_launcher"  
  13.         android:label="@string/app_name"  
  14.         android:theme="@style/AppTheme" >  
  15.           
  16.     ……  
  17.   
  18.         <service android:name="com.example.servicetest.MyService" >  
  19.         </service>  
  20.     </application>  
  21.   
  22. </manifest>  


然后修改activity_main.xml中的代码,在布局文件中添加用于绑定Service和取消绑定Service的按钮:

[html] view plain copy
  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.     <Button  
  7.         android:id="@+id/start_service"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="Start Service" />  
  11.   
  12.     <Button  
  13.         android:id="@+id/stop_service"  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="wrap_content"  
  16.         android:text="Stop Service" />  
  17.   
  18.     <Button  
  19.         android:id="@+id/bind_service"  
  20.         android:layout_width="match_parent"  
  21.         android:layout_height="wrap_content"  
  22.         android:text="Bind Service" />  
  23.       
  24.     <Button   
  25.         android:id="@+id/unbind_service"  
  26.         android:layout_width="match_parent"  
  27.         android:layout_height="wrap_content"  
  28.         android:text="Unbind Service"  
  29.         />  
  30.       
  31. </LinearLayout>  
接下来再修改MainActivity中的代码,让MainActivity和MyService之间建立关联,代码如下所示:
[java] view plain copy
  1. public class MainActivity extends Activity implements OnClickListener {  
  2.   
  3.     private Button startService;  
  4.   
  5.     private Button stopService;  
  6.   
  7.     private Button bindService;  
  8.   
  9.     private Button unbindService;  
  10.   
  11.     private MyService.MyBinder myBinder;  
  12.   
  13.     private ServiceConnection connection = new ServiceConnection() {  
  14.   
  15.         @Override  
  16.         public void onServiceDisconnected(ComponentName name) {  
  17.         }  
  18.   
  19.         @Override  
  20.         public void onServiceConnected(ComponentName name, IBinder service) {  
  21.             myBinder = (MyService.MyBinder) service;  
  22.             myBinder.startDownload();  
  23.         }  
  24.     };  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.         startService = (Button) findViewById(R.id.start_service);  
  31.         stopService = (Button) findViewById(R.id.stop_service);  
  32.         bindService = (Button) findViewById(R.id.bind_service);  
  33.         unbindService = (Button) findViewById(R.id.unbind_service);  
  34.         startService.setOnClickListener(this);  
  35.         stopService.setOnClickListener(this);  
  36.         bindService.setOnClickListener(this);  
  37.         unbindService.setOnClickListener(this);  
  38.     }  
  39.   
  40.     @Override  
  41.     public void onClick(View v) {  
  42.         switch (v.getId()) {  
  43.         case R.id.start_service:  
  44.             Intent startIntent = new Intent(this, MyService.class);  
  45.             startService(startIntent);  
  46.             break;  
  47.         case R.id.stop_service:  
  48.             Intent stopIntent = new Intent(this, MyService.class);  
  49.             stopService(stopIntent);  
  50.             break;  
  51.         case R.id.bind_service:  
  52.             Intent bindIntent = new Intent(this, MyService.class);  
  53.             bindService(bindIntent, connection, BIND_AUTO_CREATE);  
  54.             break;  
  55.         case R.id.unbind_service:  
  56.             unbindService(connection);  
  57.             break;  
  58.         default:  
  59.             break;  
  60.         }  
  61.     }  
  62.   
  63. }  

可以看到,这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBinder的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。

当然,现在Activity和Service其实还没关联起来了呢,这个功能是在Bind Service按钮的点击事件里完成的。可以看到,这里我们仍然是构建出了一个Intent对象,然后调用bindService()方法将Activity和Service进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service。



3. Service分类



3.1 Service的类型


分类

3.2 详细介绍


具体demo参考:


http://www.jianshu.com/p/e04c4239b07e

5. 使用场景

  • 通过上述描述,你应该对Service类型及其使用非常了解;
  • 那么,我们该什么时候用哪种类型的Service呢?
  • 各种Service的使用场景请看下图:

    使用场景

6. 其他思考

6.1 Service和Thread的区别

  • 结论:Service和Thread之间没有任何关系
  • 之所以有不少人会把它们联系起来,主要因为Service的后台概念

    后台的定义:后台任务运行完全不依赖UI,即使Activity被销毁,或者程序被关闭,只要进程还在,后台任务就可以继续运行

  • 其实二者存在较大的区别,如下图:


    Paste_Image.png

一般来说,会将Service和Thread联合着用,即在Service中再创建一个子线程(工作线程)去处理耗时操作逻辑,如下代码:

@Override  public int onStartCommand(Intent intent, int flags, int startId) {  //新建工作线程    new Thread(new Runnable() {          @Override          public void run() {              // 开始执行后台任务          }      }).start();      return super.onStartCommand(intent, flags, startId);  }  class MyBinder extends Binder {      public void service_connect_Activity() {    //新建工作线程        new Thread(new Runnable() {              @Override              public void run() {                  // 执行具体的下载任务              }          }).start();      }  }

6.2 Service和IntentService的区别

具体别人写的文章:Android多线程全面解析:IntentService用法&源码













转载:http://blog.csdn.net/guolin_blog/article/details/11952435

http://www.jianshu.com/p/d963c55c3ab9