zoukankan      html  css  js  c++  java
  • Service和Thread的关系及如何启用Service,如何停用Service

    Service和Thread的关系:

    不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Thread之间没有任何关系!
     
    之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的,你还会觉得它和Thread有什么关系吗?让我们看一下这个残酷的事实吧。
     
    在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:
     
    [java] view plaincopy
    Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  
    然后在MyService的onCreate()方法里也加入一行打印当前线程id的语句:
    [java] view plaincopy
    Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());  
    现在重新运行一下程序,并点击Start Service按钮,会看到如下打印日志:
     
                                     
    可以看到,它们的线程id完全是一样的,由此证实了Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定会出现ANR的。
     
    你可能会惊呼,这不是坑爹么!?那我要Service又有何用呢?其实大家不要把后台和子线程联系在一起就行了,这是两个完全不同的概念。Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,前面不是刚刚验证过Service是运行在主线程里的么?在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。
     
    额,既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。
     
    启动和停用service:

    服务的开发比较简单,如下:

    第一步:继承Service类

    public classSMSService extends Service {}

    第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:<service android:name=".SMSService"/>

    服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

    如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

    如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。

     

    服务常用生命周期回调方法如下:

    onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。

    onDestroy()该方法在服务被终止时调用。

    与采用Context.startService()方法启动服务有关的生命周期方法

    onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。

    与采用Context.bindService()方法启动服务有关的生命周期方法

    onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。

    onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用

  • 相关阅读:
    ASP.NET AJAX 1.0 英文文档,视频教程
    第十五篇: Ajax Control Toolkit 控件包3. DragPanel (拖动效果)
    第二篇: Silverlight 下载与安装
    第十二篇: Ajax Control Toolkit 控件包1. Accordion (多层折叠效果)
    第一篇: Silverlight 效果展示
    第十四篇: 建立 AJAX 母版页 (为了后面例子方便)
    第三篇: Silverlight 2.0 下载与安装
    第十三篇: Ajax Control Toolkit 控件包2. CollapsiblePanel (展开和折叠效果)
    第十六篇: Ajax Control Toolkit 控件包4. DropShadow (阴影效果)
    ENDNOTE使用方法(转发)
  • 原文地址:https://www.cnblogs.com/joey-hua/p/4741608.html
Copyright © 2011-2022 走看看