ImageVerifierCode 换一换
格式:DOC , 页数:13 ,大小:85.22KB ,
资源ID:2989762      下载积分:150 文钱
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,省得不是一点点
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenke99.com/d-2989762.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Adnroid Server深入解析.doc)为本站会员(11****ws)主动上传,文客久久仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文客久久(发送邮件至hr@wenke99.com或直接QQ联系客服),我们立即给予删除!

Adnroid Server深入解析.doc

1、Android 的 Service 深入分析(全) 1.先来看看 What is Service?A Service is not a separate process And A Service is not a thread. 一个服务不是一个独立的进程,也不是一个线程。那 Service 是什么呢?后台运行 处理耗时较长的工作Service 是一个应用程序组件Service 没有图形化界面Service 通常用来处理一些耗时比较长的操作可以使用 Service 更新 ContentProvider,发送 Intent 以及启动系统的通知等等2. 接着来看看 Service 的整个生命周期

2、:Service 的活动生命周期是在 onStart()之后,这个方法会处理通过startServices()方法传递来的 Intent 对象。音乐 Service 可以通过开打intent 对象来找到要播放的音乐,然后开始后台播放。Service 停止时没有相应的回调方法,即没有 onStop()方法。onCreate()方法和 onDestroy()方法是针对所有的 Services,无论它们是否启动。通过 Context.startService()和 Context.bindService()方法。然而,只有通过 startService()方法启动的 Service 才会被调用 on

3、Start()方法。如果一个 Service 允许别人绑定,那么需要实现以下额外的方法:IBinder onBind(Intent intent)boolean onUnbind(Intent intent)void onRebind(Intent intent)onBind()回调方法会继续传递通过 bindService()传递来的 intent 对像。onUnbind()会处理传递给 unbindService()的 intent 对象。如果Service 允许绑定,onBind()会返回客户端与服务互相联系的通信频道。如果建立了一个新的客户端与服务的链接,onUnbind()方法可以请

4、求调用onRebind()方法。下面的图表介绍了 Service 的回调方法,然而,它把通过startService()方法建立的服务从通过 bindService()方法建立的服务分离开。记住任何服务,无果它怎样建立,都默认客户端可以链接,所以任何的Service 能够接收 onBind()和 onUnbind()方法。 3. Service 组件的通信方式一共有三种:(1)通过 startService 来启动的Service;(2)通过 bindService 来启动的 Service;(3)使用 AIDL 方式的Service,下面我们来看看它们的具体使用方法,和它们之间有什么区别。(

5、1)首先来说说通过 startService 来启动的 Service(后台处理工作)startService(Intent service),通过 intent 值来指定启动哪个Service,可以直接指定目标 Service 的名,也可以通过 Intent 的 action 属性来启动设置了相应 action 属性的 Service,使用这种方式启动的 Service,当启动它的 Activity 被销毁时,是不会影响到它的运行的,这时它仍然继续在后台运行它的工作。直至调用StopService(Intent service)方法时时或者是当系统资源非常紧缺时,这个服务才会调用 onDes

6、tory()方法停止运行。所以这种 Service 一般可以用做,处理一些耗时的工作。可能有人会问,如果 Service 不是独立的一个进程的话,为什么当 Activity 退出时,Service 仍然可以进行运行呢?其实是这样的,sdk 上说了 activity 和 service 默认是运行在应用进程的主线程中,四大组件默认都是和activity 运行在同一个主线程中的,那就是说 activity 通过 startservice 方法启动一个服务后,被启动的服务和 activity 都是在同一个线程中的。所以当我主动销毁了这个 activity,但是他所在的线程还是存在的,只不过是这个 a

7、ctivity 他所占用的资源被释放掉了,这个 activity 所在的主线程只有当 android 内存不足才会被杀死掉,否则一般的情况下这个 activity 所在的应用程序的线程始终存在,也就是这个 activity 所启动的服务也会一直运行下去。还有一点需要注意的是,如果 Service 要处理一些比较耗时的工作时,因为 Service 和 Activity 默认情况都在同一个主线程中的缘故,所以要操作这些耗时的工作一般是在Service 里另起一个新线程来处理。这样可以避免主线程的阻塞,影响用户体验性。(2)然后来说说通过 bindService 来启动的 Service(在本地同进

8、程内与Activity 交互)这里举一个实例来讲:首选,创建一个接口,IServicepackage yy.android.servicepublic interface IService String getName(); 接着,创建一个服务 LocalService package yy.android.service;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;publi

9、c class LocalService extends Serviceprivate static final String TAG=“LocalService“;private MyBind myBind=new MyBind(); public IBinder onBind(Intent intent) Log.d(TAG, “localService onBind“);return myBind; Overridepublic void onCreate() super.onCreate();Log.d(TAG, “localService onCreate“);Overridepub

10、lic void onDestroy() super.onDestroy();Log.d(TAG, “localService onDestroy“);Overridepublic void onStart(Intent intent, int startId) / TODO Auto-generated method stubsuper.onStart(intent, startId); Log.d(TAG, “localService onStart“); Overridepublic boolean onUnbind(Intent intent) / TODO Auto-generate

11、d method stubLog.d(TAG, “localService onUnBind“);return super.onUnbind(intent); public class MyBind extends Binder implements IServicepublic String getName() / TODO Auto-generated method stubreturn “YUZHIBOYI“; 最后就是实现 ServiceActivity 了:package yy.android.service;import android.app.Activity;import an

12、droid.os.Bundle;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder; import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText

13、;public class ServiceActivity extends Activity private static final String TAG=“ServiceActivity“;private IService iService=null;private EditText edit;private Button mBind; ServiceConnection connection=new ServiceConnection() public void onServiceDisconnected(ComponentName name) Log.d(TAG,“DisConnect

14、ion“);System.out.println(“DisConnection!“);public void onServiceConnected(ComponentName name, IBinder service) / TODO Auto-generated method stub Log.d(TAG,“Connection“);System.out.println(“Connection!“);iService=(IService)service;edit.setText(iService.getName();/ text.setText(iService.getName(); Ove

15、rride public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.main);/ Log.d(TAG,“Start“);edit =(EditText)findViewById(R.id.edit); mBind = (Button)findViewById(R.id.Connection);mBind.setOnClickListener(new OnClickListener() public void onClick(View v

16、) Intent intent=new Intent(ServiceActivity.this,LocalService.class);bindService(intent,connection, BIND_AUTO_CREATE); );AndroidManifest.xml 注册 LocalService布局文件:当运行程序是,日志信息是这样的:05-10 13:46:28.353: D/LocalService(1328): localService onCreate05-10 13:46:28.353: D/LocalService(1328): localService onBind

17、05-10 13:46:28.385: D/ServiceActivity(1328): Connection当点击模拟器的 back 按钮时,日志信息: 05-10 13:46:57.953: D/LocalService(1328): localService onUnBind05-10 13:46:57.953: D/LocalService(1328): localService onDestroy从日志信息可以分析出,整个程序的运行过程是这样的:点用户点击绑定服务按钮时 Activity 调用 bindService()方法,然后系统就去 调用 onCreate 创建服务,然后系统继

18、续调用 onBind()方法向 Activity 传递一个 IBinder 类型的对象, 是传递给 Activity 里的 ServiceConnection 里的onServiceConnected(ComponentName name, IBinder service)的第二个参数,然后通过这个参数可以获得 IService 的方法。进行本地的 Activity 和Service 交互。(在同一个进程里进 行的),当用户点击 back 建时,系统就调用 onUnbind()再接着调用 onDestory()方法销毁服务。总结可以理解 成:bindSevice()-onCreate()-on

19、Bind()-onServiceConnected();这里需要 注意的一点是,启动的 LocalService 是和 ServiceActivity 在同一个进程里的,因为在注册服务时,没有配置它的 android:process = “xxxx“ 属性。具体android:process 的用法可以自己去看其他资料。(3)最后要说的是使用 AIDL 方式的 Service(进行跨进程的通信)AIDL(Android Interface Definition Language) IPC 机制是面向对象的,轻量级的。通过 AIDL 定义的接口可以实现服务器端与客户端的 IPC 通信。在Andr

20、oid 上,一个进程不能简单的像访问本进程 内存一样访问其他进程的内存。所以,进程间想要对话,需要将对象拆解为操作系统可以理解的基本数据单元,并且有序的通过进程边界。通过代码来实现这个数据 传输过程是冗长乏味的,所幸的是 android 提供了 AIDL 工具来帮我们完成了此项工作。注意:仅仅在你需要 A 应用程序的客户端访问 B 应用程序的服务器端来实现 IPC 通信,并且在服务器端需要处理多线程(客户端)访问的情况下使用AIDL。如果不需要使用到进程间的 IPC 通信,那么通过 Binder 接口实现将更 为合适,如果需要实现进程间的 IPC 通信,但不需要处理多线程(多客户端),通过 M

21、essager 接口来实现将更为合适。不管怎样,在使用 AIDL 之前, 应先确保已理解了 Bound Service。AIDL 接口的调用采用的是直接的函数调用方式,但你无法预知哪个进程(或线程)将调用该接口。同进程的线程调用和其他进程调用该接口之间是有所区别的: 在同进程中调用 AIDL 接口,AIDL 接口代码的执行将在调用该 AIDL 接口的线程中完成,如果在主 UI 线程中调用 AIDL 接口,那么 AIDL 接 口代码的执行将会在这个主 UI 线程中完成。如果是其他线程,AIDL 接口代码的执行将在 service 中完成。因此,如果仅仅是本进程中的线程访问该服 务,你完全可以控制

22、哪些线程将访问这个服务(但是如果是这样,那就完全没必要使用 AIDL 了,而采取 Binder 接口的方式更为合适)。 远程进程(其他线程)调用 AIDL 接口时,将会在 AIDL 所属的进程的线程池中分派一个线程来执行该 AIDL 代码,所以编写 AIDL 时,你必须准备好可能有未知线程访问、同一时间可能有多个调用发生(多个线程的访问),所以 ADIL 接口的实现必须是线程安全的。 可以用关键字 oneway 来标明远程调用的行为属性,如果使用了该关键字,那么远程调用将仅仅是调用所需的数据传输过来并立即返回,而不会等待结 果的返回,也即是说不会阻塞远程线程的运行。AIDL 接口将最终将获得一

23、个从 Binder 线程池中产生的调用(和普通的远程调用类似)。如果关键字 oneway 在本地调用中被使用,将不会对函数调用有任何影响。 定义 AIDL 接口AIDL 接口使用后缀名位.aidl 的文件来定义,.aidl 文件使用 java 语法编写,并且将该.aidl 文件保存在 src/目录下(无论是服务端还是客户端都得保存同样的一份拷贝,也就是说只要是需要使用到该 AIDL 接口的应用程序都得在其src 目录下拥有一 份.aidl 文件的拷贝)。编译时,Android sdk 工具将会为 src/目录下的.aidl 文件在 gen/ 目录下产生一个 IBinder 接口。服务端必须相应

24、的实现该 IBinder 接口。客户端可以绑定该服务、调用其中的方法实现 IPC 通信。创建一个用 AIDL 实现的服务端,需要以下几个步骤: 1. 创建.aidl 文件:该文件(YourInterface.aidl)定义了客户端可用的方法和数据的接口2. 实现这个接口:Android SDK 将会根据你的.aidl 文件产生 AIDL 接口。生成的接口包含一个名为 Stub 的抽象内部类,该类声明了所有.aidl 中描述的方法,你必须在代码里继承该 Stub 类并且实现.aidl 中定义的方法。3.向客户端公开服务端的接口:实现一个 Service,并且在 onBinder 方法中返回第 2

25、 步中实现的那个Stub 类的子类(实现类)。注意:服务端 AIDL 的任何修改都必须的同步到所有的客户端,否则客户端调用服务端得接口可能会导致程序异常(因为此时客户端此时可能会调用到服务端已不再支持的接口1. 创建.aidl 文件AIDL 使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他 AIDL 生成的接口。重要的是必须导入所有非内置类型,哪怕是这些类型是在与接口相同的包中。默认的 AIDL 支持一下的数据类型(这些类型不需要通过 import 导入): java 语言的原始数据类型(包括 int, long, char, boolen

26、 等等) String CharSequence:该类是被 TextView 和其他控件对象使用的字符序列 List:列表中的所有元素必须是在此列出的类型,包括其他 AIDL 生成的接口和可打包类型。List 可以像一般的类(例如 List)那样使用,另一边接收的具体类一般是一个 ArrayList,这些方法会使用 List接口 Map:Map 中的所有元素必须是在此列出的类型,包括其他 AIDL 生成的接口和可打包类型。一般的 maps(例如 Map)不被支持,另一边接收的具体类一般是一个 HashMap,这些方法会使用 Map 接口。对于其他的类型,在 aidl 中必须使用 import

27、导入,即使该类型和 aidl 处于同一包内。定义一个服务端接口时,注意一下几点: 方法可以有 0 个或多个参数,可以使空返回值也可以返回所需的数据。 所有非原始数据类型的参数必须指定参数方向(是传入参数,还是传出参数),传入参数使用 in 关键字标记,传出参数使用 out,传入传出参数使用 inout。如果没有显示的指定,那么将缺省使用 in。 在 aidl 文件中所有的注释都将会包含在生成的 IBinder 接口中(在Import 和 pacakge 语句之上的注释除外)。 aidl 中只支持成员方法,不支持成员变量。 我们通过一个例子来说明:(服务端)YAIDLService 工程里的包

28、yy.service.aidl 有以下三个文件IAIDLService.aidlpackage yy.service.aidl; interface IAIDLService String getName(); 将该.aidl 文件保存在工程目录中的 src/目录下,当编译生成 apk 时,sdk 工具将会在 gen/ 目录下生成一个对应的 IBiner 接口的.java 文件。如果使用 eclipse 编写 app,那么这个 IBinder 接口文件将会瞬间生成。生成的接口包含一个名为 Stub 的抽象的内部类,该类声明了所有.aidl 中描述的方法,注意:Stub 还定义了少量的辅助方法,

29、尤其是 asInterface(),通过它或以获得 IBinder(当 applicationContext.bindService()成功调用时传递到客户端的 onServiceConnected())并且返回用于调用 IPC 方法的接口实例YAIDLService.javapackage yy.service.aidl;import yy.service.aidl.IAIDLService.Stub;import android.app.Service;import android.content.Intent;import android.os.IBinder;import androi

30、d.os.RemoteException;public class YAIDLService extends ServiceOverridepublic IBinder onBind(Intent intent) / TODO Auto-generated method stubreturn mBinder;private IAIDLService.Stub mBinder = new Stub() public String getName() throws RemoteException return “YUZHIBOYI“; ;在服务端里的服务程序里实现接口。这样,mBinder 就是一个 Stub 类得对象,该对象为 service 提供了 IPC 接口,并将会向客户端公 开,这样客户端就可以通过该对象与该 service 进行交互了。现在,如果客户端(比如一个Activity)调用 bindService()来连接该服 务端(YAIDLService) ,客户端的 onServiceConnected()回调函数将会获得从服务端(YAIDLService )的onBind()返回的 mBinder 对象实现 ADIL 接口时需要注意一下几点: 不能保证所有对 aidl 接口的调用都在主线程中执行,所以必须考虑多线程调用的情况,也就是必须考虑线程安全。

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。