LaPlayer(1)------Service浅析

  Service是一个长期运行在后台,并不提供界面的应用组件。其他组件可以启动一个服务,并且即使用户切换到其他的应用,该服务仍可在后台继续运行。另外,组件可以把某个服务邦定到自己,来与其交互通信,甚至包括执行进程间通信(IPC)。因此在播放器的开发中,为了让播放音乐不依赖于具体的Activity,将播放音乐的控制放于Service中。

  Service和Activity一样,需要在AndroidMainfest.xml中进行配置,配置如下:

1         <service
2             android:name="com.porco.service.PlayService"   android:exported="false">
3             <intent-filter>
4                 <action android:name="PlayService" />
5             </intent-filter>
6         </service>        

在此处设置了android:exported这个属性。这是用于指示该服务是否能够被其他应用程序组件调用或跟它交互:如果设置为true,则能够被调用或交互,否则不能。设置为false时,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。
 它的默认值依赖与该服务所包含的过滤器。没有过滤器则意味着该服务只能通过指定明确的类名来调用,这样就是说该服务只能在应用程序的内部使用(因为其他外部使用者不会知道该服务的类名),因此这种情况下,这个属性的默认值是false。另一方面,如果至少包含了一个过滤器,则意味着该服务可以给外部的其他应用提供服务,因此默认值是true,此种情况下在Eclipse中会有警告信息:Exported service does not require permission。

  Service的使用方式有两种:context.s在tartService() 和 context.bindService()。其生命周期分别是:

  context.startService() 启动流程:

  context.startService()  -> onCreate()  -> onStartCommand()  -> Service running  -> context.stopService()  -> onDestroy()  -> Service stop

  如果Service还没有运行,则android先调用onCreate(),然后调用onStartCommand();

  如果Service已经运行,则只调用onStartCommand(),所以一个Service的onStartCommand方法可能会重复调用多次。

  如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。

  所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy

  context.bindService()启动流程:

  context.bindService()  -> onCreate()  -> onBind()  -> Service running  -> onUnbind()  -> onDestroy()  -> Service stop

  onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。

  所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。

  在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

  在具体使用时,可分为以下三种情况:

  1.startService启动服务。

  2.bindService启动服务。

  3.startService & bindService 启动服务。

  为了测试不同情况下的service的调用及生命周期,编写测试demo代码如下:

Activity部分·:

public class PlayActivity extends Activity {

    private Intent intent=new Intent("tService");
    private Button mButtonBind;
    private Button mButtonUnbind;
    private Button mButtonplay;
    private Button mButtonStart;
    private Button mButtonStop;
    TestService tService;

    ServiceConnection conn=new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            Log.d("activity1","service service disconnected");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            //System.out.println("bind ok");
            Log.d("activity1","service connnected");
            tService=((TestService.MBinder) service ).getService();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player);
        //bindService(intent, conn, BIND_AUTO_CREATE);

        mButtonBind=(Button)findViewById(R.id.buttonbind);
        mButtonUnbind=(Button)findViewById(R.id.buttonunbind);
        mButtonplay=(Button)findViewById(R.id.buttonserviceplay);
        mButtonStart=(Button)findViewById(R.id.buttonstart);
        mButtonStop=(Button)findViewById(R.id.buttonstop);

        mButtonBind.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                bindService(intent, conn, BIND_AUTO_CREATE);
                Log.d("activity1","activity after bindservice");
            }
        });

        mButtonUnbind.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                unbindService(conn);
                Log.d("activity1","activity after unbindservice");
            }
        });

        mButtonplay.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tService.play();
            }
        });

        mButtonStart.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                startService(intent);
                Log.d("activity1","start service");
            }
        });

        mButtonStop.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                stopService(intent);
                Log.d("activity1","stop service");
            }
        });

    }
}

Service部分:

public class TestService extends Service {

    private Thread mThread;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d("service","onbind");
        return new MBinder();
    }

    class MBinder extends Binder{
        public TestService getService(){
            return TestService.this;
        }
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.d("service","service create");
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        super.onDestroy();
        Log.d("service","service destory");

    }

    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d("service","service unbind");
        return super.onUnbind(intent);

    }

    @Override
    public void onRebind(Intent intent) {
        // TODO Auto-generated method stub
        super.onRebind(intent);
        Log.d("service","service rebind");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.d("service","service start");
        return super.onStartCommand(intent, flags, startId);
    }

    public void play(){
        Log.d("service","service play");

    }

}

  1.startService启动服务:用于启动一个服务执行后台任务,不进行通信,停止服务使用stopService。点击按钮调用startService()方法,输出结果如下:

  2.bindService启动服务:该方法启动的服务要进行通信,停止服务使用unbindService。点击按钮调用bindService()方法,输出结果如下:

  3.startService & bindService 启动服务:Service将会一直在后台运行,同时调用stopService和unbindService才能停止服务。输出结果(一种)如下:

综合以上,可以得出:

  1.在Service未启动时,无论是调用startService 还是 bindService 方法,都会先调用service的onCreate()方法创建一个service服务。

  2.在Service创建后销毁前,如果调用startService方法,每调用一次都会触发一次service的onStartCommand()方法;如果调用bindService方法,如果已绑定,则不会再触发service的onBind方法。

  3.如果要销毁service,则需要调用对应的方法:startService--stopService ,bindService--unbindService,startService & bindService--stopService &unbindService,才会触发service的onDestory方法。

  

  此外,有一点需要注意的是,在执行bindService方法后,下一个语句的执行先于service的创建,因此,需要注意对于binder返回的对象的使用,防止出错。具体service和activity在同一进程中的运行关系及情况需要后续学习。

参考文档:

Android Service 服务(一)—— Service

Android 中的 Service 全面总结

时间: 2024-08-25 16:11:55

LaPlayer(1)------Service浅析的相关文章

Net Remoting和Web Service浅析

.Net Remoting和Web Service浅析(转) 随着.NET的推出,微软引入了一套新的通讯技术:Web Services和.NET remoting..NET remoting和ASP.NET Web Services可以为建立分布式的应用提供强有力的支持.因此,为了在我们的应用程序中选择合适的技术,充分理解这两种技术的工作原理是非常必要的. Web Service技术使用了HTTP.XML和SOAP技术进行通 讯,因此,Web Service是跨平台的和真正的跨越防火墙的B2B应

Android中远程Service浅析

上一篇文章中简单的写了一下关于Android中Service的两种启动方式,不过都是本地的服务,今天就简单的写下关于Android中远程Service的使用,学习之前先了解两个概念,AIDL( Android Interface definition language)字面上的意思就是借口定义语言,专业一点理解就是Android进程之间通信的借口描述语言.IPC(Inter-Process Conmmunication)内部进程之间的通信,同一个手机上,如果你的APP需要访问调用另外一个APP的

小猪的Android入门之路 Day 9 part 1

小猪的Android入门之路 Day 9 part 1 Android四大组件之--Service浅析 --转账请注明出处:coder-pig 本节引言: 在前面的学习中我们已经把安卓四个基本组件中的两个: Actvity(活动)和BroadCastReceiver过了一遍,而在Day 9中我们会对第三个组件Service进行 解析,两种类型的Service,Service的生命周期,如何去使用Service,声明Service,调用,停止Service; 跨进程调用AIDL,以及常用的系统服务

我的Android学习之旅

去年大概在七月份的时候误打误撞接触了一阵子Android,之后由于工作时间比较忙,无暇顾及,九月份的时候自己空闲的时间比较多,公司相对来说加班情况没以前严重.开启了个人的Android学习之旅,初衷是想将Android的博客做个索引文章的,不过想想还可以分享一些学习中的历程,算是对自己的Android学习 有个交代吧.由于在公司有工作,学习的时间通常就是周一到周五晚上的时间和周末时间,周一到周五晚上的时间不确定,因此牺牲了大量的周末时间来学习Android,有点像苦行僧,时间段持续了三个多月.如

Service框架浅析Google-Guava Concurrent

Guava包里的Service接口用于封装一个服务对象的运行状态.包括start和stop等方法.例如web服务器,RPC服务器.计时器等可以实现这个接口.对此类服务的状态管理并不轻松.需要对服务的开启/关闭进行妥善管理.特别是在多线程环境下尤为复杂.Guava包提供了一些基础类帮助你管理复杂的状态转换逻辑和同步细节. 使用一个服务 一个服务正常生命周期有: Service.State.NEWService.State.STARTINGService.State.RUNNINGService.S

Mosquitto pub/sub服务实现代码浅析-主体框架

Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来说,简单许多. MQTT采用二进制协议,而不是XMPP的XML协议,所以一般消息甚至只需要花费2个字节的大小就可以交换信息了,对于移动开发比较有优势. IBM虽然开源了其MQTT消息协议,但是却没有开源其RSMB服务端程序,不过还好目前有比较稳定的实现可用,本文的Mosquitto是其中比较活跃的实

Android基础入门教程——4.2.3 Service精通

Android基础入门教程--4.2.3 Service精通 标签(空格分隔): Android基础入门教程 本节引言: 本节,我们继续来研究Service(服务)组件,本节将会学习下Android中的AIDL跨进程通信的一些 概念,并不深入到源码层次,暂时知道是什么,会用即可!开始本节内容~ 本节对应官方文档:Binder 1.Binder机制初涉 1)IBinder和Binder是什么鬼? 我们来看看官方文档怎么说: 中文翻译: IBinder是远程对象的基本接口,是饿了高性能而设计的轻量级

Android L 漫游浅析

这篇文章主要是分析在Android L 源代码中对手机漫游的处理.当然我这里所说的漫游指的是国际漫游.通常我们判断手机是否在国际漫游,第一个想法就是比较网络上获取的MCC+MNC是否与手机中的IMSI相同,如果不同就判断为漫游了.如果是漫游的话,手机上最直观的可以看到就是两个地方了: a . 手机的屏幕的状态拦上手机信号角标的左下方是否有"R"显示. b . Setting --->About phone --->Status --->Roming 当然这是最粗略的比

android学习笔记--android启动过程之init.rc文件浅析

1.  init.rc文件结构文件位置:init.c  : /system/core/initinit.rc  : /system/core/rootdir 首先init.rc文件是以模块为单位的,每个模块里的内容都是一起执行的,模块分为3种类型:on.service.import.我们可以看下init.rc文件是怎么写的:1.import import /init.usb.rc import /init.${ro.hardware}.rc import /init.trace.rc 上面的内容