![Service与多线程_v1_5[1][1].26.ppt_第1页](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a1.gif)
![Service与多线程_v1_5[1][1].26.ppt_第2页](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a2.gif)
![Service与多线程_v1_5[1][1].26.ppt_第3页](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a3.gif)
![Service与多线程_v1_5[1][1].26.ppt_第4页](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a4.gif)
![Service与多线程_v1_5[1][1].26.ppt_第5页](http://file1.renrendoc.com/fileroot2/2020-1/17/6e87ff69-9b3a-4030-b0a8-650f4b50094a/6e87ff69-9b3a-4030-b0a8-650f4b50094a5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android Service与多线程,1.Service,简介,Android提供Service类用于创建隐形的,不需要用户接口的程序。Service其实就是没有专属界面的Activity。 通过Service可以使程序在退出之后仍然能够对事件或用户操作做出反应,或者在后台继续运行某些程序功能。例如在退出播放器界面之后,继续在后台播放音乐,还有浏览器在后台下载网络数据。 Android赋予Services比处于不活动(inactivity)的Activities更高的优先级,所以它们的进程不会轻易被系统杀掉。 在某些极端的情况下(例如为前台Activity提供资源),Service可能会被杀
2、掉,但是只要有足够的资源,系统会自动重启Service。,简介,在某些需要确保用户体验的情况下,(例如播放音乐)Service也可以被提高到与前台进程相同的优先级。 Service是由其他Service,Activity或者Broadcast Receiver开始,停止和控制。,简介,Service的生命周期状态比Activity少一些,只有Create,Bind,Start,Unbind,Destroy,这也是与Activity的不同之处。 通过startService启动的Service的生命周期状态。 通过bindService启动的Service的生命周期(稍后介绍),onCreate
3、,onDestroy,onUnbind,onBind,onCreate,onDestroy,onStart,开始和停止Service,开启Service 在Activity中可以通过startService(Intent)开启一个Service。与Activity跳转类似。 Intent intent = new Intent(this,MyService.class); startService(intent); 其中MyService类是开发者自定义的继承Service的子类。 关闭Service 在Activity中通过stopService(Intent)关闭Service; Inte
4、nt intent = new Intent(this,MyService.class); stopService(intent); 或者在Service中通过stopSelf()关闭自身。,如何实现一个Service,建立Android工程 Activity:ServiceApplication.java 程序入口,例程将在在这个Activity中启动Service。 Service:MyService.java 自定义Service。,如何实现一个Service,MyService.java public class MyService extends Service Override p
5、ublic IBinder onBind(Intent intent) / 必须实现的接口 return null; Override public int onStartCommand(Intent intent, int flags, int startId) return Service.START_STICKY; Override public boolean onUnbind(Intent intent) return super.onUnbind(intent); Override public void onDestroy() super.onDestroy(); ,如何实现一个
6、Service,ServiceApplication.java public class ServiceApplication extends Activity Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = new Intent(this,MyService.class); startService(intent); ,如何实现一个Service,在Android
7、Manifest.xml中注册这个Service ,如何实现一个Service,在很多情况下,你可能需要重写onCreate和onStartCommand方法 onStartCommand方法在使用startService方法启动Service的时候被调用,在Service的生命周期内会多次被调用。 onStartCommand方法代替了Android 2.0之前一直使用的onStart方法。通过onStartCommand方法,我们可以明确告诉操作系统,在用户调用stopService或者stopSelf方法显式停止之前被操作系统杀死的Service重启的时候要执行的操作。,如何实现一个Se
8、rvice,Override public int onStartCommand(Intent intent, int flags, int startId) return Service.START_STICKY; 通过onStartCommand返回的Service常量,我们可以明确指定系统在重启由于资源抢占被杀死的Service时执行的行为。 Service.START_STICKY 重写onStartCommand和返回Service.START_STICKY实现与Android 2.0之前onStart相同的效果。 Service. START_REDELIVER_INTENT Se
9、rvice.START_NOT_STICKY (详见SDK),如何实现一个Service,本地进程(Local process) AndroidManifest.xml中,节点下的android:process属性是可选项。这个选项告诉系统运行Service的进程的名称。一般情况下,节点下的任何程序组件都是运行在创建程序的缺省进程中。但是通过重写这个属性,我们可以重新定义运行Service的进程。 远程进程(Remote process) 如果属性是以”:”开头的字符串(例如”:remote”),那么程序将创建新的进程运行Service。 如果属性是其他名称,那么程序将在该名称的全局进程下运行
10、Service。,如何实现一个Service,如果Service运行于本地进程中,那么在Service中进行大规模计算、文件读写、互联网连接时也会阻塞UI线程,影响用户体验。 通常的做法是在onStartCommand中创建子线程,在子线程中进行耗时的操作,操作结束时停止Service。或者通过远程进程运行Service。,绑定Activity和Service,由于Service没有界面,所以用户控制Service需要通过另外一个Activity来接收用户输入。 然后,通过绑定Activity与Service,可以实现Activity与Service之间的交互。例如在Activity中控制音乐
11、播放Service对音乐进行开始/停止,快进/快退等操作。 如果Service运行在本地进程,即与Activity属于同一进程,则只要在Activity中获得指向Service的引用,就可以像调用成员对象的方法一样去调用Service的方法。,绑定Activity和Service,如果Service运行在远程进程中,则Activity与Service的交互属于进程间通讯。跟其他操作系统一样,Android操作系统也对进程空间进行保护,一个进程不能直接访问另一个进程的内存空间。 所以进程间数据交互需要利用Android操作系统提供的进程间通讯(IPC)机制来实现。,IPC机制IBinder,IB
12、inder是远程对象的基本接口,是为高效率进程中、进程间通讯设计的轻量级远程过程调用机制的核心。这个接口描述了与远程对象交互的抽象协议。通常我们使用的时候并不是直接实现这个接口,而是继承自Binder父类。,绑定Activity和Service,Activity和Service交互示意图,Activity,Binder,Service,IBinder,绑定Activity和Service,MyService.java public class MyService extends Service private IBinder mBinder = new MyBinder(); Override
13、 public IBinder onBind(Intent intent) / 必须实现的接口 return mBinder; public class MyBinder extends Binder Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException return super.onTransact(code, data, reply, flags); ,绑定Activity和Service,ServiceApplication.
14、java public class ServiceApplication extends Activity private IBinder mBinder; private ServiceConnection mConnection; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); mConncetion = new ServiceConnection() Override public void
15、 onServiceConnected(ComponentName name, IBinder service) mBinder = service; Override public void onServiceDisconnected(ComponentName name) mConnection = null; ; Intent intent = new Intent(this,MyService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); ,绑定Activity和Service,onService
16、Connection的输入参数IBinder就是Service中onBind返回的Binder对象。通过IBinder对象就可以实现Activity和Service进程间通讯。 通过配对的IBinder的transact()方法和Binder的onTransact()方法,可以实现从IBinder接口发送消息,在Binder对象中接收消息,处理消息,再返回的过程。,绑定Activity和Service,要注意,transact()和onTransact()是一个同步调用过程,意味着线程A调用transact()后,在线程B完成onTransact()整个处理过程之前,线程A都是阻塞着。所以,如
17、果在onTransact()中需要进行大规模计算时,通常需要在线程A中开启新线程调用transact()。,绑定Activity和Service,onTransact(int code, Parcel data, Parcel reply,int flags) transact(int code, Parcel data, Parcel reply,int flags) 通过onTransact和transact交互的数据都被封装在Parcel中 由于IBinder只提供了一个消息传递接口,只能通过int类型的输入参数code对消息进行识别和判断,AIDL简介,AIDL(Android Int
18、erface Description Language)弥补了IBinder接口单一的缺点。 AIDL接口描述文件,语法与普通的Java接口一样,只是文件扩展名为.aidl。 ADT会根据这个描述文件自动生成一个底层基于IBinder机制,表层提供描述文件所定义方法的接口类。,AIDL简介,Aidl文件示例,例子中我们自定义了set、get两个方法 ITest.aidl interface IAidlTest /可以看到,aidl文件语法与普通接口一致 void set(int i); int get(); ,AIDL简介,ADT会根据这个.aidl文件,自动生成一个.java接口文件,其中代
19、码结构如下: public interface IAidlTest extends android.os.IInterface /部分省略 public static abstract class Stub extends android.os.Binder implements com.book.ServiceApplication.IAidlTest /部分省略 private static class Proxy implements com.book.ServiceApplication.IAidlTest /部分省略 public void set(int i) throws and
20、roid.os.RemoteException /implement./ public int get() throws android.os.RemoteException /implement./ /需要在服务端重写set、get函数,实现具体操作 public void set(int i) throws android.os.RemoteException; public int get() throws android.os.RemoteException; ,AIDL简介,AIDL接口代码结构如下,可以看出这里采用了COM组件开发的Proxy/Stub结构,这种代理设计模式多用于远
21、程对象的调用。,AIDL interface,Proxy,Stub,Service,Activity,Process A,Process B,AIDL使用,MyService.java部分带啊 通过匿名类,实现服务端(stub端)的方法 private final IAidlTest.Stub binder = new IAidlTest.Stub() Override public void set(int i) throws RemoteException /在这里实现set方法 Override public int get() throws RemoteException /在这里实验
22、get方法 ; Override public IBinder onBind(Intent intent) return binder; ,AIDL使用,ServiceApplication.java部分代码 ServiceConnection mSrcConn = new ServiceConnection() Override public void onServiceConnected(ComponentName name, IBinder service) /这里stub.asInterface其实就是返回一个代理(Proxy)对象 IBinder mBinder = IAidlTes
23、t.Stub.asInterface(service); Override public void onServiceDisconnected(ComponentName name) /省略部分代码 ;,2.多线程,多线程应用,为了提供良好的用户体验,我们必须保证程序有高响应性,所以不能在UI线程中进行耗时的计算或IO操作。 而且,Android操作系统在下面情况下会强制关闭程序 UI线程在5秒内没有响应 广播对象不能再10秒内完成onReceive方法,多线程应用,因此我们采用多线程的方法,将大规模的计算放在后台线程中进行计算,然后将计算结果再反映前台。例如,在后台下载网络图片,下载完成后显
24、示在屏幕上。,新建用户线程,Java基础 Thread mThread = new Thread() Override public void run() timeConsumingProcess(); ; mThread.start(),新建用户线程,但是由于Android操作系统的线程安全机制,我们不能在非UI线程中重绘UI,所以在用户线程中进行类似更改进度条,修改TextView文字等操作都会造成程序强制关闭(FC) Android提供了两种方法解决上述问题: Handler AsyncTask,Handler机制,Android操作系统在UI线程中,缺省维护这一个MessageQueue和一个Looper。 Looper伪码 While(true) Msg =getFirstMessage(MessageQueue) if(Msg != null) processMessage() ,Handler机制,Looper通过一个死循环,当有消息Message加入队列时,通过FIFO的顺序处理消息。 一个Message中包括了处理Message的Handler对象还有消息内容。 这种机制对应这设计模式中的命令模式 Handler与UI线程是同一个线程,所以我们在用户线程中完成计算之后,可以通过向消息队列加入一个消息,通知特定的Hand
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年汽车美容师技能框架图解试题及答案
- 汽车维修工考试中常见问题的解决方案试题及答案
- 2024年CPBA考试的注意事项试题及答案
- 国际宠物营养标准对比考题试题及答案
- 2024年六年级语文实际应用试题及答案
- 二手车评估中的质量控制与监测试题及答案
- 二手车评估师考试常见问题及试题及答案
- 2024年计算机基础考试自信应战及答案
- 2024年计算机基础学习路径试题及答案
- 幼儿园指导纲要培训:艺术领域
- 风景园林基础试题及答案
- 2025-2030年中国喷涂加工行业市场全景调研及未来趋势研判报告
- 人工智能素养测试题及答案(初中版)
- 人教版八年级下册语文第三单元测试题含答案
- 四年级下册《生活·生命.安全》全册教案
- 2025年河南工业和信息化职业学院单招职业技能测试题库带答案
- 《园林微景观设计与制作》课件-项目一 园林微景观制作准备
- 打开“心”世界与“压力”和解-2025年春季学期初中生心理健康主题教育班会课件
- 2025年湖南邵阳新宁县城乡建设发展集团有限公司招聘笔试参考题库附带答案详解
- 福建省2025届中考生物押题试卷含解析
- 试机协议合同范本
评论
0/150
提交评论