资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2020/6/2,#,第九章 服务,9.1 Android,多线程编程,9.5,实战演练,9.3,服务的生命周期,9.2,服务的基本用法,9.4,更多服务使用技巧,9.6,小结,9.1 Android,多线程编程,Service,(服务)是一个长期运行在后台的用户组件,没有用户界面,是,Android,中实现程序后台运行的解决方案,非常适合去执行那些不需要和用户交互而且还要求长期运行的任务。,服务的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。,服务并不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程,且服务不会自动开启线程,所有代码都是默认运行在主线程中,因此我们需要在服务内部手动创建子线程,并在子线程内部执行具体任务,以防止主线程被阻塞。,接下来我们学习一下,Android,多线程的知识。,9.1.1,线程的,基本用法,Android,中的多线程和,Java,中多线程的用法基本类似,定义一个线程的时候只需要新建一个继承自,Thread,的类,并且重写父类的,run(),方法,在该方法中编写耗时操作逻辑即可,,示例如下:,通过,创建,MyThread,的实例,然后让这个实例调用,start(),方法,这样,run(),方法中的代码就可以在子线程中运行,,示例如右图所示,:,class MyThread extends Thread,Override,public void run(),/,具体处理逻辑,9.1 Android,多线程编程,new MyThread().start();,在实际应用中为了避免继承中的高耦合性,一般会选择使用实现,Runnable,接口的方法定义线程,示例如下:,相应的,这样定义线程的方式使启动线程的方式也发生改变,示例如下:,class MyThread implements Runnable,Override,public void run(),/,具体处理逻辑,9.1 Android,多线程编程,MyThread myThread=new MyThread();,new Thread(myThread).start();,如果在编码中我们不想专门定义一个类去实现,Runnable,接口,也可以选择使用匿名类的方式编写,示例如下:,new Thread(new Runnable(),Override,public void run(),/,具体逻辑处理,).start();,9.1 Android,多线程编程,9.1.2,更新,UI,Android,系统的,UI,是线程不安全的,也就是说,如果想要更新应用程序里的,UI,元素,必须在主线程中进行,否则程序会出现异常崩溃。,Android,为了解决这个问题提供了一套异步消息处理机制,完美的解决了在子线程中进行,UI,操作的问题。,通过教材案例,P217,演示,Android,异步消息处理机制。,9.1 Android,多线程编程,9.1.3 Handler,消息机制,Android,中异步消息处理机制也就是,Handler,消息处理机制。,主要由,4,各部分组成:,Message,、,Handler,、,MessageQueue,和,Looper,。,处理过程:在主线程中绑定,Handler,对象,并在事件触发上面创建子线程用于完成耗时操作,当子线程中的工作完成后,会向,Handler,对象发送一个已完成的信号(,Message,对象),主线程中的,Handler,收到信号后,会进行主线程,UI,更新。,9.1 Android,多线程编程,组成部分介绍:,Message-,在线程之间传递的消息,它可以通过在内部携带少量信息在不同线程之间交换数据。,Message,的,what,字段可以用来携带整型数据,,obj,字段可以用来携带,Object,对象。,Handler-,是处理者的意思,主要用于发送消息和处理消息。一般使用,Handler,对象的,sendMessage(),方法发送消息,发送的消息经过一系列处理后,最终会传递到,Handler,对象的,handleMessage(),中。,9.1 Android,多线程编程,MessageQueue-,消息队列的意思,主要用来存放通过,Handler,发送的消息。通过,Handler,发送的消息会存在,MessageQueue,中等待处理,每个线程只有一个,MessageQueue,对象。,Looper-,是线程中,MessageQueue,的管家,调用,Looper,的,loop(),方法后,就会进入到无限循环,每当发现,MessageQueue,中存在信息就会取出并传递到,Handler,的,handleMeesage(),方法中。,9.1.4,实战演练,打开网络图片,2,3,功能描述:,技术要点:,用户交互界面的设计与实现,界面逻辑代码的设计与实现,添加访问网络权限,案例代码(详见教材,P220P224,),实现步骤:,通过网络浏览器打开服务器端图片并刷新界面,使用,HttpHRLConnection,的,get,请求获取网络图片,运用,Handler,机制刷新主线程,1,9.1 Android,多线程编程,9.1.5,异步任务,AsyncTask,的使用,实际开发中,为了更加方便我们在子线程中对,UI,进行操作,,Android,还提供了一个必学的好用工具,AsyncTask,,它是,Android,给我们提供的一个处理异步任务的类。,可以实现,UI,线程和后台线程的通讯,后台线程执行异步任务,并把结果返回给,UI,线程。,9.1 Android,多线程编程,为什么需要使用异步任务,保证了,UI,的稳定性以及准确性,同时避免多个线程同时对,UI,进行操作造成,UI,混乱;,Google,规定,Android 4.0,以后访问网络操作这样的耗时操作必须放在子线程中,以免造成任务阻塞抛出,Application Not Responsed(ANR),错误。,AsyncTask,为何而生,Android,给我们提供了一个封装好的组件,AsyncTask,,可以方便的实现异步任务处理,同时也可以在子线程中更新,UI,,并且封装简化了异步操作;,AsyncTask,封装,了,使用,线程以及线程池处理异步任务涉及到线程同步以及管理问题,的,过程,使我们方便的在子线程中更新,UI,。,9.1 Android,多线程编程,构建,AsyncTask,子类的泛型参数,AsyncTask,是一个抽象类,所以我们想使用它必须创建一个子类去继承它。在继承的同时我们可以为,AsyncTask,指定,3,个泛型参数,这,3,各参数的用途如下:,Params,:启动任务时输入的参数类型。,Progress,:后台任务执行中返回的进度值的类型。,Result,:后台任务执行完成后返回记过的类型。,9.1 Android,多线程编程,构建,AsyncTask,子类的回调方法,AsyncTask,中主要有以下几个方法:,doInBackground(Param),onPreExecute(),:,onPostExecute(Result),:,onProgressUpdate(Progress),参考案例见书本,P225-228,页,9.1 Android,多线程编程,服务(,Service,)是,Android,四大组件之一,服务也有很多重要的知识点,接下来我们从最基本的开始学习。,9.2,服务的基本用法,9.2.1,服务的创建,服务的创建方式与广播接收者类似,只需要在项目的程序包名上单击右键,选择性,【,new,】,【,Service,】,【,Service,】,选项,接着在弹出窗口,图,9-6,所示,中输入服务的名称即可,。,9.2,服务的基本用法,Exported,属性表示是否允许当前程序之外的其他程序访问这个服务,,Enabled,属性表示是否启用这个服务,我们将这两个选项都勾选,点击,Finish,完成创建,9.2.2,服务的启动与停止,创建好服务后,接下来我们来学习服务的启动以及停止的方法,在代码中主要依靠,Intent,来实现。,首先在,onCreate(),方法中获取按钮实例并注册点击事件,然后在点击事件中构建,Intent,对象,并调用,startService(),方法来启动服务,调用,stopService(),方法来停止服务,因为这两个方法是定义在,Context,中的因此我们可以直接调用。注意,这种启动方式完全由活动来决定服务何时停止,如果不点击,STOP SERVICE,按钮停止服务,服务会一直处于运行状态。,9.2,服务的基本用法,9.2.3,服务的通信,Android,中允许活动,Activity,与服务之间进行通信,借助创建服务时默认生成的,onBind(),方法就可以实现。,任何一个服务在整个应用程序范围内都是通用的,也就是说服务不仅可以和活动进行绑定,也可以和任何一个其他活动进行绑定。,示例代码参考,P233-236,9.2,服务的基本用法,服务的启动方式分为两种,分别是,startService(),方法和,bindService(),方法。,服务根据启动方式的不同,也有其自己不同的生命周期。,9.3,服务的生命周期,onCreate(),:第一次创建服务是执行的方法;,onDestroy(),:服务被销毁时执行的方法;,onStartCommand(),:客户端通过调用,startService(),方法启动服务时执行该方法;,onBind(),:客户端通过调用,bindService(),方法启动服务时执行的方法;,onUnbind(),:客户端调用,unBindService(),方法断开服务器绑定时执行的方法。,9.4.1,使用前台服务,前台服务的特点是会一直有一个正在运行的图标在系统栏显示,下拉状态栏后可以看到更加详细的信息,类似于通知的效果。,Android 8.0,及以上系统为了提高电池续航时间而引入了一系列后台执行限制及变更,其中就包括前台服务以及通知的变更。,Android 9.0,或更高版本在使用前台服务时必须请求,FOREGROUND_SERVICE,权限,否则运行程序则系统会引发,SecurityException,错误,9.4,更多服务使用技巧,9.4.2 IntentService,的使用,在开发安卓应用的过程中,我们经常需要这样的场景:希望,APP,在不影响当前用户的操作的前提下,在后台默默的做一些任务。,为了可以简单的创建一个异步的、会自动停止的服务,,Android,专门提供了一个,IntentService,类,这个类会在任务执行完成后自行结束而不需要外部调用,stopSelf(),方法了,这样就很好的解决了前面提到的两种尴尬。,Android Studio,提供的快捷方式也支持创建,IntentService,,大家可以尝试,此处我们使用手动方式创建。,9.5,更多服务使用技巧,9.5,实战演练,下载,2,3,功能描述:,技术要点:,添加依赖,使用,OkHttp,协议进行网络请求,使用异步任务,AsyncTask,进行下载并刷新界面,解析下载出来的数据,通知更新,案例代码(详见教材,P242P252,),实现步骤:,运用服务功能实现网络下载,实现服务中经常会用到的在后台运行下载,1,9.5,实战演练,下载,9.6,小结,本章主要讲解了服务相关的重要知识点,包括,Android,多线程编程、服务的基础知识、服务的生命周期、前台服务以及,IntentService,等知识。知识涵盖大部分日常开发中会用到的服务技术,最后通过综合案例展示了前面章节知识点的综合运用,初学者需要熟练掌握并运用。,大连理工大学出版社,THANKS!,
展开阅读全文