Android开发之Service学习笔记
来源:互联网 发布:hadoop2.4.1源码下载 编辑:程序博客网 时间:2024/05/29 04:00
断断续续学Android也有1年多了,内心一直摇摆不定,犹豫着要不要往这方向发展下去。因为自己是C++出身的,对语言这方面内心总有那么点偏见;经过1年多的徘徊,总算认清了事实,开发你总得基于某一平台吧,而市面上基于纯C++开发的太少了(主要是自己能力不够);自己身边目标明确的同事,他们成长的速度快得惊人,看着就很是嫉妒,所以啊,我也必须找准目标,然后锲而不舍。先从Android应用开发入手,慢慢地再往系统层研究。从现在开始要养成写博客的习惯,记录学习的点滴,也见证自己的成长。
唠叨了这么多,也该进入正题了。第一篇博客,我想记录一下Android的四大组件之一Service。对于Service,一开始我以为就是一线程,只不过是Android的开发团队给它起了个响亮的别名,但事实上并不是,它依然是在主线程中执行它的生命周期;既然不是线程,也就是说不能在它的生命周期里执行耗时的操作,那它到底有什么用呢?等我们分析完就知道原因啦!
Service它有两种启动方式:
1、Started:通过调用startService()来启动Service;
2、Bound:通过调用bindService()来启动Service;bound服务提供了一个客户端/服务器接口,实现组件与服务间通讯,还可以实现进程间通讯(IPC)。多个组件可以同时与一个服务绑定,不过需要等到所有的组件都解绑了后,服务才会被销毁。
对于startService这种启动方式,第一次调用的时候会走一下onCreate,再走onStartCommand方法,之后再次startService,只会走onStartCommand,一般这种启动方式主要用来处理一些耗时的操作,如网络资源的下载;常见的写法是在onStartCommand中启动一线程来执行耗时操作:
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {new Thread(new Runnable() { @Override public void run() { // do something here } }).start();return super.onStartCommand(intent, flags, startId);}
服务一启动之后就一直保持运行的状态,直到stopService()或stopSelf()方法被调用才消亡。无论调用多少次startService(),只要调用1次stopService()或stopSelf()方法,服务就会停止。对于这种方式启动的服务,基本与组件没什么联系了,默默地干活,默默地消亡。
为了实现组件与服务间能够通讯,需要使用bindService启动服务;这种方式我们会用到onBind()方法,获取Binder对象;
public class MyService extends Service { private final static String TAG = "MyService"; private MyBinder mBinder = new MyBinder(); public class MyBinder extends Binder { public void doSomething() { new Thread(new Runnable() { @Override public void run() { // do something here Log.i(TAG, "doSomething"); } }).start(); } } @Override public IBinder onBind(Intent intent) { return mBinder; }}
这样我们就可以在组件中通过ServiceConnection的回调来实现通讯了;
private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { ((MyService.MyBinder)service).doSomething(); } @Override public void onServiceDisconnected(ComponentName name) { }};通过以下代码启动服务:
Intent intent = new Intent(MainActivity.this, MyService.class);bindService(intent, mConn, BIND_AUTO_CREATE);解邦也很简单:
unbindService(mConn);
以下是两种方式的生命周期流程图:
最后,我们还要在AndroidManifest.xml中添加Service的注册。
<service android:name=".MyService" />
现在我们有个疑问,Service既通过startService启动,又通过bindService绑定,这是完全有可能的,那它怎样才能销毁呢(走onDestroy()方法)?因为服务一启动或被绑定后,它就一直处于运行状态,所以必须同时调用stopService()和unbindService()方法,才能销毁该服务。
目前为止,我们都是在自己进程内进行通讯,现修改一下AndroidManifest.xml:
<service android:name=".MyService" android:process=":remote"/>
使服务在另一进程中启动,但我们会发现,执行bindService后程序会崩溃,这是因为组件和服务在不同进程,它们不能用传统的方式建立连接。这种情况下我们就需要用到AIDL(Android Interface Definition Language)来进行跨进程通讯了(IPC)。
现添加一aidl文件IMyAidlInterface.aidl:
// IMyAidlInterface.aidlpackage com.example.service;// Declare any non-default types here with import statementsinterface IMyAidlInterface { void doSomething();}修改一下原来MyService.java的代码,将之前自定义Binder类中的操作移到下面:
IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public void doSomething() throws RemoteException { // do something here Log.i(TAG, "doSomething"); }};在我们的onBind()方法中返回上面的mBinder对象。
我们组件中建立连接的回调接口也要修改一下:
private ServiceConnection mConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { try { IMyAidlInterface.Stub.asInterface(service).doSomething(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { }};到这里我们的服务就可以正常的跨进程与我们的组件进行通讯了。
目前为止我们都只是在单个应用内通讯,为了实现不同应用间可以建立联系,我们可以将服务端的aidl接口(文件包名必须完全一样)提供给客户端调用,达到以上那种跨进程间通讯。
讲了那么多关于Service的知识,那么它到底有什么用呢?Service没有界面,它可以后台运行(也可以前台,通过startForeground),另一个作用就是我们上面一直在讲的跨进程通讯。
好啦!第一次写博客,就先写这么多吧!
- Android开发笔记之《Service学习》
- Android应用开发学习笔记之Service
- Android开发学习笔记之service
- Android开发之Service学习笔记
- Android开发学习笔记之 Service 的使用
- android学习笔记之Service
- Android学习笔记之Service
- Android之Service学习笔记
- Android学习笔记之Service学习笔记
- Android学习笔记之Service的 学习
- Android开发学习笔记-9 Service基础
- android开发笔记之service(一)
- android学习笔记之十服务(Service)
- android学习笔记之十服务(Service)
- Android学习笔记--四大组件之Service
- 学习笔记:Android基本组件之Service
- Android学习笔记四大组件之Service
- Android学习笔记五之Service
- Poj 1961 Period
- 单片机轻松入门之三:蜂鸣器
- hrbust 哈理工oj 1570 田忌赛马【贪心】
- 链表
- 基于STM32红外计数的灯光照明
- Android开发之Service学习笔记
- MySql数据库的简介
- 强大的oracle函数wm_concat
- 一份面试题的总结 2
- 【POJ】2031 - Building a Space Station(克鲁斯塔尔)
- Android本地数据安全尝试(上)——SQLCipher
- argc 和 argv 经典实例 --写的真好
- json错误(没有转化为javascript的错误)
- uboot-的start.S详细注解及分析