Service是android四大组件之一,没有用户界面,一直在后台运行。

为什么使用Service启动新线程执行耗时任务,而不直接在Activity中启动一个子线程处理?

1、Activity会被用户退出,Activity所在的进程就变成了空进程(没有任何活动组件的进程),系统需要内存可能会优先终止该进程;

2、如果宿主进程被终止,那么该进程内所有的子线程也会被终止,这样可能导致子线程无法执行完成;

3、其实两种方式都是可以处理耗时任务的,使用场景不同而已。

一、通过Start方式启动Service

这种方式启动的Sevice,访问者与service之间没有关联,即使访问者退出Service仍然执行

生命周期:onCreate()->onStartCommand()->onDestroy()

》定义一个继承Service的子类

public class NormalService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
        Log.d("NormalService", "启动成功");
        //一般在这里启动新线程执行耗时的操作
        return super.onStartCommand(intent, flags, startId);
    }
}

》在AndroidManifest.xml文件中配置该Service

<service android:name="com.android.servicetest.service.NormalService" />

》在activity中使用

private void startNormal() {
    nomalIntent = new Intent();
    nomalIntent.setClass(this, NormalService.class);
    startService(nomalIntent);
}

二、通过bind方式启动Service

这种方式启动的Sercice,访问者与Service绑定在一起,访问者退出,Service也就终止了

生命周期:onCreate()->onBind()->onUnbind()->onDestroy()

》定义一个继承Service的子类

public class BinderService extends Service {

    private int count;
    private MyBinder mBinder;

    @Override
    public IBinder onBind(Intent arg0) {
        if (mBinder == null) {
            mBinder = new MyBinder();
        }
        Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
        Log.d("BinderService", "绑定成功");
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new Runnable() {

            @Override
            public void run() {
            while (true) {
                try {
                Thread.sleep(1000);
                count++;
                } catch (Exception e) {

                }
            }
            }
        }).start();
    }

    public class MyBinder extends Binder {
        public int getCount() {
            return count;
        }
    }
}

》在AndroidManifest.xml文件中配置该Service

<service android:name="com.android.servicetest.service.BinderService" />

》在activity中使用

private MyBinder mBinder;

private ServiceConnection conn = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName arg0) {

    }

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
    mBinder = (BinderService.MyBinder) binder;
    }
};

private void bindService() {
    bindIntent = new Intent();
    bindIntent.setClass(this, BinderService.class);
    bindService(bindIntent, conn, Service.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(conn);
}

Binder对象相当于Service组件的内部钩子,关联到绑定的Service组件;

当其他的程序组件绑定该Service时,Service会把Binder对象返回给其他程序组件,其他程序组件通过该Binder对象即可与Service组件进行实时通信。

三、IntentService,处理异步请求的服务

IntentService是Service的子类,它增加了额外的功能:

使用队列来管理请求Intent,每当客户端代码通过Intent请求启动IntentService时,IntentService会将该Intent加入队列中,然后开启一条新的worker线程处理队列中的Intent,因此不会阻塞主线程。

IntentService会按次序处理队列中的Intent,该线程保证同一时刻只处理一个Intent。

》IntentService的实现

public class IntentServiceTest extends IntentService{

    public IntentServiceTest() {
        super("IntentService");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
        Log.d("IntentServiceTest", "启动成功");
        //该方法可以执行耗时的操作
        long endTime = System.currentTimeMillis() + 20 * 1000;
        while(System.currentTimeMillis() < endTime){
            synchronized (this) {
            try{
                wait(endTime - System.currentTimeMillis());
            }catch(Exception e){

            }
            }
        }
    }
}

》在AndroidManifest.xml文件中配置该Service

<service android:name="com.android.servicetest.service.IntentServiceTest" />

》在activity中使用

private void startIntentService(){
    serviceIntent = new Intent();
    serviceIntent.setClass(this, IntentServiceTest.class);
    startService(serviceIntent);
}

四、跨进程调用Service(AIDL Service)

Android各应用程序都运行在自己的进程中,进程之间无法直接进行数据交换,为了事项这种跨进程通信,Android提供了AIDL Service。

》创建AIDL文件,定义接口的源代码必须以.aidl结尾

package com.android.servicetest.service;

interface IMusic{
    String getName();
    String getYear();
}

定义好AIDL接口之后,ADT工具会自动在gen/com/android/servicetest/service/目录生成一个IMusic接口;

在该接口里包含一个Stub内部类,该内部类除了实现IMusic接口还实现了IBinder接口,这个Stub类将会作为远程Service的回调类。

》定义一个Service实现类

public class MusicService extends Service{

    private MusicBinder mBinder;

    @Override
    public IBinder onBind(Intent arg0) {
        if(mBinder == null){
            mBinder = new MusicBinder();
        }
        Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
        Log.d("MusicService", "绑定成功");
        return mBinder;
    }

    public class MusicBinder extends IMusic.Stub{

        @Override
        public String getName() throws RemoteException {
            return "本草纲目";
        }

        @Override
        public String getYear() throws RemoteException {
            return "2006";
        }

    }
}

》在AndroidManifest.xml文件中配置该Service

<service android:name="com.android.servicetest.service.MusicService" />

》在activity中使用

private IMusic musicService;

private ServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName arg0) {

    }

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
        //获取远程Service的OnBind方法返回的对象的代理
        musicService = IMusic.Stub.asInterface(binder);
    }
};

private void bindAidlService(){
    aidlIntent = new Intent();
    aidlIntent.setClass(this, MusicService.class);
    bindService(aidlIntent, connAidl, Service.BIND_AUTO_CREATE);
}

private void showContent() {
    String content = "";
    try {
        content = musicService.getYear() + musicService.getName();
    } catch (Exception e) {
    }
    Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(connAidl);
}

这种方式和绑定本地Service的差别很小,只是获取Service回调的方式有区别:

绑定本地Service时可以直接获取OnBind方法的返回值;绑定远程Service时获取的事OnBind方法返回的对象的代理。

Android服务(Service)研究的更多相关文章

  1. Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?

    Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...

  2. Android服务Service总结

    转自 http://blog.csdn.net/liuhe688/article/details/6874378 富貴必從勤苦得,男兒須讀五車書.唐.杜甫<柏學士茅屋> 作为程序员的我们, ...

  3. android服务Service(上)- IntentService

    Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...

  4. Android服务——Service

    服务 Service 是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到服务,以与之进行 ...

  5. Android服务Service

    安卓Service服务 一    Service简介 Service是运行在后台的,没有界面的,用来处理耗时比较长的.Service不是一个单独的进程,也不是一个单独的线程. Service有两种类型 ...

  6. android 服务service开启和关闭

    startService()方法开启一个服务. 服务只会开启一次,如果服务已经创建,并且没有销毁,多次调用startService方法只会执行onStartCommand方法和onStart方法. 服 ...

  7. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  8. Android服务之Service(其一)

    android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...

  9. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

随机推荐

  1. MathType 6.9 介绍安装

    1.介绍 MathType是强大的数学公式编辑器,与常见的文字处理软件和演示程序配合使用,能够在各种文档中加入复杂的数学公式和符号,可用在编辑数学试卷.书籍.报刊.论文.幻灯演示等方面,是编辑数学资料 ...

  2. tyvj1011 传纸条

    背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端, ...

  3. R语言-用R眼看琅琊榜小说的正确姿势

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html 目录: 零:写在前面的一些废话 一.R眼看琅琊榜的基本原理 1.导入数据 2.筛选数据 3.多条 ...

  4. JSON.parse和eval的区别

    JSON.parse和eval的区别 JSON(JavaScript Object Notation)是一种轻量级的数据格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是Jav ...

  5. 在android程序中加入widget(窗口小部件)并与之交互的关键代码

    摘要: widget(窗口小部件)可以增强应用程序的交互性, 是很多应用中都会用到的功能,本文不求大而全,但是会给出程序与widget交互的关键代码 正文: 其实widget是嵌入(embedded) ...

  6. SVN 删除误上传到服务器的文件

    使用Axure软件的时候,不小心把一些无用的文档也提交到了SVN上了. 当更新服务器上的文件到本地,然后删除误提交的文件时,出现了一个错误,见下图:   错误:cannot verify lock o ...

  7. JavaScript——之对象参数的引用传递

    今天碰到一个问题,怎样把参数变更影响到函数外部,如: <script> var myname = "wood"; A(myname); document.write(m ...

  8. Java 深拷贝、浅拷贝及Cloneable接口

    Cloneable接口是一个空接口,仅用于标记对象,Cloneable接口里面是没有clone()方法,的clone()方法是Object类里面的方法!默认实现是一个Native方法 protecte ...

  9. 5.openstack之mitaka搭建计算节点

    部署计算节点(compute服务) 一:控制节点配置 1.建库建用户 CREATE DATABASE nova_api; CREATE DATABASE nova; GRANT ALL PRIVILE ...

  10. 集合List内容

    集合List内容 这次我们学习的主要内容为:集合框架 List 一  集合框架介绍   List集合与数组的区别: 不同点:1> 数组的长度在使用前必须确定,一旦确定不能改变.而List集合长度 ...