一、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,完全不需要担心无法对后台任务进行控制的情况。

[Android]Android四大组件之Service总结的更多相关文章

  1. Java乔晓松-android的四大组件之一Service(服务的绑定)

    android的四大组件之一Service(服务的绑定) 怎么绑定服务,又怎么解除服务,代码如下: MainActivity.java源码: package com.example.lesson14_ ...

  2. Android开发四大组件之Service(具体解释篇)

    Android开发之四大组件--Service 一.Service 简单介绍 Service是android系统中的四大组件之中的一个(Activity.Service.BroadcastReceiv ...

  3. Android Studio四大组件之Service

    Service在Android运行在后台,它没有可视化界面,只是默默运行在后台.我们以一个后台定时器的例子清晰的说明Service的运行流程. 一.创建Service类 项目右键->New-&g ...

  4. Android四大组件之Service

    Android四大组件之Service Android支持服务的概念,服务是在后台运行的组件,没有用户界面,Android服务可用有与活动独立的生命周期.Android支持两种类型的服务: 本地服务: ...

  5. Android深入四大组件(七)Service的绑定过程

    前言 我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读Android深入四大 ...

  6. 【Android开发日记】之入门篇(五)——Android四大组件之Service

    这几天忙着驾校考试,连电脑都碰不到了,今天总算告一段落了~~Service作为Android的服务组件,默默地在后台为整个程序服务,辅助应用与系统中的其他组件或系统服务进行沟通.它跟Activity的 ...

  7. Android 四大组件之 Service(一)

    Service是Android中四大组件之一,在Android开发中起到非常重要的作用,它运行在后台,不与用户进行交互. 1.Service的继承关系: java.lang.Object → andr ...

  8. Android深入四大组件(六)Service的启动过程

    前言 此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程.建议阅读此篇文章前,请先阅读Android深入四大组件(一 ...

  9. Android的四大组件之Activity

    Android的四大组件之Activity Activity:是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,B ...

  10. android中四大组件之间相互通信

    好久没有写有关android有关的博客了,今天主要来谈一谈android中四大组件.首先,接触android的人,都应该知道android中有四大组件,activity,service,broadca ...

随机推荐

  1. IP地址-计算机网络

    如需转载请联系:fengxw6@mail2.sysu.edu.cn 未经许可,禁止转载. ---Sun Yat-sen University 冯兴伟 1.  MAC地址和IP地址都是全局的(全球分配) ...

  2. Mysql远程登陆错误:ERROR 2003

    不能远程登陆Mysql,错误:ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.0.114' (10060).原因是电脑防火墙 ...

  3. 自用的弹出窗口jquery插件

    现有网上的弹出窗口插件很多, 但发现在项目应用中总会有些功能不能适用, 最后只好自己写一个:插件主要参考了ymPrompt弹窗代码, ymPrompt是JS的弹窗,本插件相当于是ymPrompt的jq ...

  4. html5--1.9 img元素嵌入图片

    html5--1.9 img元素嵌入图片 学习要点: img元素嵌入图片学习一个新属性:title 1.img的属性 1.src:必要属性,制定图片来源的路径; 2.alt属性:当图片无法显示时的替代 ...

  5. kvm初体验之三:vm的安装及管理

    Host: CentOS release 6.4 (Final) Guest: CentOS release 6.6 (Final) 全程以root身份操作 1. host上创建桥br0 参考< ...

  6. 分享知识-快乐自己:初识 Hibernate 概念片(一)

    1):什么是 Hibernate? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibe ...

  7. Facebook的实时流处理技术——Scuba是Facebook的一个非常快速、分布式的内存数据库,用于实时分析和查询

    Scuba,Facebook的一个非常快速.分布式的内存数据库,用于实时分析和查询.是Facebook的回归分析代码.错误报告监控.广告收入监控和性能调试的背后主力. Facebook的实时流处理技术 ...

  8. linux命令学习笔记(52):ifconfig命令

    许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有 一个类似的工具,也就是ifconfig (interfaces config).通 ...

  9. Posix线程编程指南(1)

    这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第一篇将向您讲述线程的创建与取消.   一.线程创建 1.1 线程与进程相对进程而言,线程是一 ...

  10. JSP常见知识点

    false 7.8 磅 0 2 false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTa ...