JavaService详解.ppt

上传人:牧羊曲112 文档编号:6509493 上传时间:2023-11-07 格式:PPT 页数:23 大小:335KB
返回 下载 相关 举报
JavaService详解.ppt_第1页
第1页 / 共23页
JavaService详解.ppt_第2页
第2页 / 共23页
JavaService详解.ppt_第3页
第3页 / 共23页
JavaService详解.ppt_第4页
第4页 / 共23页
JavaService详解.ppt_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《JavaService详解.ppt》由会员分享,可在线阅读,更多相关《JavaService详解.ppt(23页珍藏版)》请在三一办公上搜索。

1、Android应用开发,2,06Java_Service,Service简介Service的启动生命周期BinderAIDL实现接口时的几个原则IPC的调用步骤,3,服务是运行在后台的一段代码。它可以运行在它自己的进程,也可以运行在其他应用程序进程的上下文(context)里面,这取决于自身的需要。其它的组件可以绑定到一个服务(Service)上面,通过远程过程调用(RPC)来调用这个方法。例如媒体播放器的服务,当用户退出媒体选择用户界面,仍然希望音乐依然可以继续播放,这时就是由服务(service)来保证当用户界面关闭时音乐继续播放的。它跟Activity的级别差不多,但是它不能自己运行,需

2、要通过某一个Activity或者其他Context对象来调用。,Service简介,Service有两种启动方式:1第一种是通过调用Context.startService()启动,调用Context.stopService()结束,startService()可以传递参数给Service。2第二种方式是通过调用Context.bindService()启动,调用Context.unbindservice()结束,还可以通过ServiceConnection访问Service。二者可以混合使用,比如说我可以先startService再bindService。,Service的启动,Servic

3、e由Activity启动,但是并不依赖于Activity,即当Activity生命周期结束时,Service仍然会继续运行。startService后,即使调用startService的进程结束了,Service仍然还存在,直到有进程调用stopService,或者Service自己自杀(stopSelf())。bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程死了,那么它bind的Service也要跟着被结束,当然期间也可以调用unbindservice让 Service结束。两种方式混合使用时,比如说你star

4、tService了,我bindService了,那么只有你stopService了而且也unbindservice了,这个Service才会被结束。,生命周期,Android系统将会尝试保留那些启动了的或者是绑定了服务的进程。如果该服务正在进程的onCreate(),onStart(),或者 onDestroy()这些方法中执行时,那么主进程将会成为一个前台进程,以确保此代码不会被停止。如果服务已经开始,那么它的主进程会就重要性而言低于所有可见的进程但高于不可见的进程,由于只有少数几个进程是用户可见的,所以只要不是内存特别低,该服务不会停止.。如果有多个客户端绑定了服务,只要客户端中的一个对于

5、用户是可见的,即认为该服务可见。如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。,生命周期,stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。所以调用startService的生命周期为:onCreate-onStart(可多次调用)-onDest

6、roy使用context.bindService()启动Service会经历:context.bindService()-onCreate()-onBind()-Service runningonUnbind()-onDestroy()-Service stop,生命周期,onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind-onDestroy相应退出。所以调用bindSe

7、rvice的生命周期为:onCreate-onBind(只一次,不可多次绑定)-onUnbind-onDestory。所以,在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。,生命周期,Android 对进程间通信实现了一套轻量级的IPC机制-Binder机制,基于此基础之上提供了整体的封装,从而实现对象代理机制。(这与COM,CORBA有相似之处,即都是基于对象代理机制。不过Android似乎只限制在本机内,而不像前者是可以跨网

8、络的)Binder工作模式1.客户端通过某种方式(后文会详细介绍)得到服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差别。它可以像其他本地对象一样调用其方法,访问其变量。2.客户端通过调用服务器代理对象的方法向服务器端发送请求。3.代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。4.服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。5.客户端收到服务器端的返回结果。,Binder,Bider机制的组成1.Binder驱动/dev/binder 是Androi

9、d内核的一个字符驱动设备,它是IPC的核心部分。客户端发送请求最终就是通过它来传递到服务端,而服务端的返回结果也是通过它来传给客户端。内核源码:binder.c2.Service Manager 顾名思义,它是负责管理服务。服务端有服务的话就得向它注册,而客户端需要向它查询、获得服务。3.提供服务的Server(Service)提供服务的Server,对普通的应用开发来讲,咱们用到的就是Service,具体的工作Android都帮忙做了封装,所以开发变得很容易。4.调用对象代理的Client(Activity)普通的应用开发来讲就是 Activity 通过代理对象去请求调用服务,注意:这个过程

10、是同步的,所以如果估计这个服务调用很耗时,那么需要考虑启新线程来调用,而不能用UI主线程。,Binder,5.代理对象(底层:BpBinder)底层代理对象工作机制:客户端进程通过服务代理BpBinder对象,调用transact函数,该函数作用就是把客户端的请求写入binder设备另一端的Service进程。从JAVA层面来讲,Android已经为我们封装定义了IBinder接口。注意:服务端Service,从底层来讲(c+)都是继承自BBinder(BBinder继承自IBinder接口),因此Service在底层需要改写BBinder的onTransact虚函数,这样当客户端请求serv

11、ice时,框架会调用相应的ServiceonTransact函数。对于JAVA层面来讲,实现Service时只需要实现AIDL定义的Stub接口就好,底层的细节系统都为咱们封装好,无需我们的关注。,Binder,Android平台提供了一种中间层语言AIDL(Android Interface Definition Language)。显然Java中不允许跨进程内存共享。因此传递对象,只能把对象拆分成操作系统能理解的简单形式,以达到跨界对象访问的目的。在Android中,则采用AIDL的方式。编译器可以通过AIDL文件生成一段代码,通过预先定义的接口达到两个进程内部通信的目的。如果需要在一个A

12、ctivity中,访问另一个Service中的某个对象,需要先将对象转化成AIDL可识别的参数(可能是多个参数),然后使用AIDL来传递这些参数,在消息的接收端使用这些参数组装成自己需要的对象。AIDL使用代理类在客户端和实现层间传递值。建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:1.在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。详细介绍见实例52的内容。,AIDL,2.如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。3.建立一个服务类(Service的子类

13、)。4.实现由aidl文件生成的Java接口。5.在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。建立AIDL服务本例中将建立一个简单的AIDL服务。这个AIDL服务只有一个getValue方法,该方法返回一个String类型的值。在安装完服务后,会在客户端调用这个getValue方法,并将返回值在TextView组件中输出。建立这个AIDL服务的步骤如下:1.建立一个aidl文件。在Java包目录中建立一个IMyService.aidl文件。IMyService.

14、aidl文件的位置如图,AIDL,AIDL,IMyService.aidl文件的内容如下:Java代码:package eoe.demo;interface IMyService String getValue();IMyService.aidl文件的内容与Java代码非常相似,但要注意,不能加修饰符(例如,public、private)、AIDL服务不支持的数据类型(例如,InputStream、OutputStream)等内容。2.如果IMyService.aidl文件中的内容输入正确,ADT会自动生成一个IMyService.java文件。读者一般并不需要关心这个文件的具体内容,也不需要

15、维护这个文件。关于该文件的具体内容,读者可以查看本节提供的源代码。3.编写一个MyService类。MyService是Service的子类,在MyService类中定义了一个内嵌类(MyServiceImpl),该类是IMyService.Stub的子类。,AIDL,MyService类的代码如下:Java代码:package eoe.demo;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public c

16、lass MyService extends Service public class MyServiceImpl extends IMyService.Stub Override public String getValue()throws RemoteException return Android/OPhone开发讲义;Override public IBinder onBind(Intent intent)return new MyServiceImpl();,AIDL,在编写上面代码时要注意如下两点:IMyService.Stub是根据IMyService.aidl文件自动生成的,一

17、般并不需要管这个类的内容,只需要编写一个继承于IMyService.Stub类的子类(MyServiceImpl类)即可。onBind方法必须返回MyServiceImpl类的对象实例,否则客户端无法获得服务对象。(4)在AndroidManifest.xml文件中配置MyService类,代码如下:Java代码:下面来编写客户端的调用代码。首先新建一个Eclipse Android工程,并将自动生成的IMyService.java文件连同包目录一起复制到工程的src目录中,如图所示。,AIDL,AIDL,调用AIDL服务首先要绑定服务,然后才能获得服务对象,代码如下:Java代码:packa

18、ge net.blogjava.mobile;import net.blogjava.mobile.aidl.IMyService;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.v

19、iew.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class Main extends Activity implements OnClickListener private IMyService myService=null;private Button btnInvokeAIDLService;private Button btnBindAIDLService;private TextView textVie

20、w;,AIDL,Override public void onServiceDisconnected(ComponentName name);Override public void onClick(View view)switch(view.getId()case R.id.btnBindAIDLService:/绑定AIDL服务 bindService(new Intent(net.blogjava.mobile.aidl.IMyService),serviceConnection,Context.BIND_AUTO_CREATE);break;case R.id.btnInvokeAID

21、LService:try textView.setText(myService.getValue();/调用服务端的getValue方法 catch(Exception e)break;,AIDL,Override public void onCreate(Bundle savedInstanceState)super.onCreate(savedInstanceState);setContentView(R.layout.main);btnInvokeAIDLService=(Button)findViewById(R.id.btnInvokeAIDLService);btnBindAIDL

22、Service=(Button)findViewById(R.id.btnBindAIDLService);btnInvokeAIDLService.setEnabled(false);textView=(TextView)findViewById(R.id.textview);btnInvokeAIDLService.setOnClickListener(this);btnBindAIDLService.setOnClickListener(this);,AIDL,实现接口时有几个原则:1.抛出的异常不要返回给调用者,跨进程抛异常处理是不可取的;2.IPC调用是同步的,如果你知道一个IPC服

23、务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。也就是IPC调用会挂起应用程序导致界面失去响应,这种情况应该考虑单起一个线程来处理;3.不能在AIDL接口中声明静态属性。,实现接口时的几个原则,IPC的调用步骤:1.声明一个接口类型的变量,该接口类型在.aidl文件中定义。2.实现ServiceConnection。3.调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递。4.在ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service)。调用YourInterfaceName.Stub.asInterface(IBinder)service)将参数转换为YourInterface类型。5.调用接口中定义的方法。你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。6.断开连接,调用接口实例中的ApplicationContext.unbindService()。,IPC的调用步骤,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号