一、Service介绍

Service是Android中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要长期运行的task。Service的运行不需要依赖于任何用户界面,即使当程序被切换到后台,霍州用户打开了另外一个app。Service仍然能够保持正常的运行。
不过需要注意的是,Service不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的app进程。当app进程被杀死,Service也会被杀死。

二、Service生命周期

. 通过startService方法 2. 通过bindService方法 这两种启动方式下的生命周期如下图所示:

Service的生命周期比起Activity要简单不少,只有onCreate()、onStartCommand()、onBind()、onDestory()。
一旦项目内任何位置调用了Context的startService(),相应的Service就会启动,并且回调onStartCommand()。如果这个Service之前还没有创建过,onCreate()会优先于onStartCommand()执行。Service启动了之后会一直保持running状态,知道stopService()或stopSelf()被调用。tips:所有Service都只会存在一个实例,所以不管调用多少次startService(),最后只需要调用一次stopService()或stopSelf()就会停下来。

另外还可以调用了Context的bindService()来获取一个Service的持久连接,这时候就会回调onBind()。如果这个Service之前还没有创建过,onCreate()会优先于onBind()执行。

三、Service的基本用法

新建一个ServiceTest项目,并新建一个MyService文件

public class MyService extends Service {  public static final String TAG = "MyService";  @Override  public void onCreate() {  super.onCreate();  Log.d(TAG, "onCreate() executed");  }  @Override  public int onStartCommand(Intent intent, int flags, int startId) {  Log.d(TAG, "onStartCommand() executed");  return super.onStartCommand(intent, flags, startId);  }  @Override  public void onDestroy() {  super.onDestroy();  Log.d(TAG, "onDestroy() executed");  }  @Override  public IBinder onBind(Intent intent) {  return null;  }  }  

在main_activity.xml文件中写入

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical" >  <Button  android:id="@+id/start_service"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="Start Service" />  <Button  android:id="@+id/stop_service"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="Stop Service" />  </LinearLayout>  

另外还有MainActivity

public class MainActivity extends Activity implements OnClickListener {  private Button startService;  private Button stopService;  @Override  protected 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);  }  @Override  public 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;  }  }  }  

最后还要在AndroidManifest.xml中进行注册,加入下面这句话

<service android:name="com.example.servicetest.MyService" >  

然后run一下,看看logcat

四、Service和Activity之间的通信

在上一节的代码中,onbind()这个方法并没有使用,其实它就是用与Service和Activity之间通信的。

我们首先在main_activity.xml中加入两个button,并修改MainActivity和MyService

public class MainActivity extends Activity implements OnClickListener {  private Button startService;  private Button stopService;  private Button bindService;  private Button unbindService;  private MyService.MyBinder myBinder;  private ServiceConnection connection = new ServiceConnection() {  @Override  public void onServiceDisconnected(ComponentName name) {  }  @Override  public void onServiceConnected(ComponentName name, IBinder service) {  myBinder = (MyService.MyBinder) service;  myBinder.startDownload();  }  };  @Override  protected 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);  bindService = (Button) findViewById(R.id.bind_service);  unbindService = (Button) findViewById(R.id.unbind_service);  startService.setOnClickListener(this);  stopService.setOnClickListener(this);  bindService.setOnClickListener(this);  unbindService.setOnClickListener(this);  }  @Override  public 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;  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;  }  }  }  
public class MyService extends Service {  public static final String TAG = "MyService";  private MyBinder mBinder = new MyBinder();  @Override  public void onCreate() {  super.onCreate();  Log.d(TAG, "onCreate() executed");  }  @Override  public int onStartCommand(Intent intent, int flags, int startId) {  Log.d(TAG, "onStartCommand() executed");  return super.onStartCommand(intent, flags, startId);  }  @Override  public void onDestroy() {  super.onDestroy();  Log.d(TAG, "onDestroy() executed");  }  @Override  public IBinder onBind(Intent intent) {  return mBinder;  }  class MyBinder extends Binder {  public void startDownload() {  Log.d("TAG", "startDownload() executed");  // 执行具体的下载任务  }  }  }  

Service和Thread的关系

首先声明Service和Thread之间没有任何关系!
之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果Service其实是运行在主线程里的,所以Service和Thread并没有什么关系
在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:

Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  

然后在MyService的onCreate()方法里也加入一行打印当前线程id的语句:

Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());  

现在重新运行一下程序,并点击Start Service按钮,可以看到,它们的线程id完全是一样的,由此证实了Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定会出现ANR的。
Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。为了避免Service导致主线程阻塞,我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。这就是Thread。
至于为什么Thread不建立在Activity中。因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

转载于:https://www.cnblogs.com/zhousysu/p/5483615.html

[Android]Android四大组件之Service总结相关推荐

  1. Android之四大组件(AIDL Service的使用)

    跨进程调用Service(AIDL Service) Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 在前一篇文章(关于Android中的四大组件(Se ...

  2. android java service_[Java教程]Android四大组件之Service浅见

    [Java教程]Android四大组件之Service浅见 0 2014-04-04 18:00:28 Service 是Android四大组件之一,可以在不显示界面的情况下在后台运行.还有一个作用是 ...

  3. Android实训课程之三 这次课老师先是提到了Android有四大组件:Activity、Service、Broadcast Receiver、Content Provider。然后重点提到Acti

    Android实训课程之三 这次课老师先是提到了Android有四大组件:Activity.Service.BroadcastReceiver.ContentProvider.然后重点提到Activi ...

  4. Android深入四大组件(八)广播的注册、发送和接收过程

    前言 我们接着来学习Android四大组件中的BroadcastReceiver,广播主要就是分为注册.接收和发送过程.建议阅读此文前请先阅读Android深入理解四大组件系列的文章,知识重复的部分, ...

  5. Android的四大组件

    Android的四大组件:Activity.Service.BroadcastReceiver.Content Provider. Content Provider 属于Android应用程序的组件之 ...

  6. Android基础四大组件详解

    Android四大组件详解 博主接触Android开发将近一年,从最初的JavaSE开始,到Android基础,一直学的糊糊涂涂,最近想整理一番 android基础, 顺便把自己的学习开发经验分享给大 ...

  7. Android 的四大组件

    目录 1.Activity 2.Service与intentService 3.LocalBroadcastManager的BroadcastReceiver 4.ContentProvider Ac ...

  8. Android 之 四大组件、六大布局、五大存储

    Android 之四大组件.六大布局.五大存储:https://blog.csdn.net/shenggaofei/article/details/52450668 Android 四大组件.五大存储 ...

  9. Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)

    相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启 ...

  10. Android基础——四大组件之Activity

    这几天继续回顾了一些Android基础方面的知识,今天跟大家一起回顾下Android四大组件中的Activity.虽然很基础,但工欲善其事,必先利其器.我们只有打好夯实的基础,才能在技术开发这条道路上 ...

最新文章

  1. 转载:js拖拽文本文档并读取内容到textarea
  2. Activity与Thread之间的通讯(old)
  3. 使用Adaptive cards来构建Teams app的界面
  4. 腾讯招.NET,居然要求精通MySQL,而不是SQLServer!
  5. Python 薪资降温?不存在的
  6. 巧用枚举CommandBehavior关闭SqlDataReader联接数据库时的conn.open状态
  7. 程序员职业6个阶段,你处于哪个?
  8. ACM-ICPC 2018 沈阳赛区现场赛 K. Let the Flames Begin (约瑟夫环问题)
  9. 栈——验证栈序列(洛谷 P4387)
  10. 东南大学RM装甲板识别算法详解
  11. 栈在括号匹配中的应用
  12. Tricks(四十)—— 神经网络解决与(或)及异或问题
  13. ajax请求完之前的loading加载
  14. 全网首发:VS编译的文件不在指定位置,怎么办
  15. 企业营销环节应用RPA的三大典型场景
  16. MySQL的一级索引和二级索引
  17. 分布式(四)——了解PRC
  18. php5 date(‘Y-m-d‘,2256946591) 显示1905 php7正常
  19. 计算机应用基础上册周测7,计算机应用基础(第3版)周南岳(win7+office10)期末复习及答案-20210614221003.docx-原创力文档...
  20. 申宝在线炒股北交所新股表现抢眼

热门文章

  1. 奇怪的车次,你信不信
  2. SIFT特征检测算子和sift = cv2.xfeatures2d.SIFT_create出错的解决办法
  3. Mac上显示出.m2文件夹并将IDEA中的Maven修改为阿里云镜像
  4. 今日恐慌与贪婪指数为65 等级转为贪婪
  5. OptionRoom推出通缩NFT质押活动,销毁15万代币
  6. 观点:比特币新一轮突破“即将到来”
  7. 微信小程序开发:学习笔记[9]——本地数据缓存
  8. 在发布ASP.NET网站的时候,出现state server错误
  9. 【模板】prim的heap优化
  10. linux内存——/proc/sys/vm/drop_caches