Android服务Service使用总结资料Word文件下载.docx
《Android服务Service使用总结资料Word文件下载.docx》由会员分享,可在线阅读,更多相关《Android服务Service使用总结资料Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。
对Service服务做好创建和注册后,就可以操作服务了。
(二)Service两种启动模式
Service的启动有两种方式:
Context.startService()和Context.bindService()。
这里的Context是上下文的意思。
1.startService()方式启动时的生命周期回调方法
(1)启动服务startService:
–>
onCreate()–>
onStart()
(2)停止服务stopService:
onDestroy()
如果调用者直接退出而没有停止Service,则Service会一直在后台运行。
这里的退走只是关闭了UI界面。
startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。
如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。
采用startService()方法启动的服务,只能调用stopService()方法结束服务,服务结束时会调用生命周期的onDestroy()方法。
2.bindService()方式启动时的生命周期回调方法
(1)绑定bindService:
onCreate()–>
onBind()
(2)解绑unbindService:
onUnbind()
(3)正常停止程序服务的方法是先解绑unbindService,再停止服务stopService。
(4)如果绑定后调用stopService方法,这时是不能停止服务的,如果这时再调用解绑unbindService,程序后先解绑,后停止服务。
用bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。
这个时候调用者和服务绑定在一起,调用者退出了,系统就会
先调用服务的onUnbind()方法,接着调用onDestroy()方法。
如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。
如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()->
onDestroy()方法。
绑定Service方法:
bindService(intent,conn,Service.BIND_AUTO_CREATE);
三个参数的说明:
第一个:
Intent对象
第二个:
ServiceConnection对象,创建该对象要实现它的onServiceConnected()和onServiceDisconnected()来判断连接成功或者是断开连接
第三个:
创建Service的模式,一般指定绑定的时候自动创建
(三)Service的五个生命周期的回调方法
1.周期命名
(1)onCreate()
(2)onStart()
(3)onBind()
(4)onUnBind()
(5)onDestroy()
2.生命周期图解
上面展示的是没有绑定服务和有绑定服务的生命周期的不同情况的过程。
3.关于几个方法的说明
(1)onCreate()说明服务第一次被创建
(2)onStartComand()说明服务开始工作
(3)onBind()说明服务已经绑定
(4)onUnBind()说明服务已经解绑
(5)onDestroy()说明服务已经停止
正如上面说的启动服务有两种方式,一个是使用startService,另一个方法是使用bindService方法;
使用bindService方法没有回调到startCommand方法;
也可以先启动服务用startService,再绑定服务用bindService,这时的Service的回调方法的顺序是:
onStartCommand()–>
onBind()
二.IntentService
普通的Service要创建一个线程去完成耗时操作,因为其运行在主线程,並且要手動停止IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。
另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UIThread),同一时间只处理一个请求。
那么,用IntentService有什么好处呢?
首先,我们省去了在Service中手动开线程的麻烦,
第二,当操作完成时,我们不用手动停止ServiceIntentService,一个方便我们处理业务流程的类,它是一个Service,但是比Service更智能
三.查看Service的生命周期回调方法的简单示例
本示例只是用来看看Service在服务开启时,停止时,绑定时,解绑时,生命周期方法的回调情况加深对Service生命周期的印象。
(一)创建MyService类(继承Service)
packagecom.lwz.service;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.support.annotation.Nullable;
/**
*服务的创建,
*测试生命周期的过程和先后
*五个生命周期:
*onCreate
*onStartCommand
*onDestroy
*onBind
*onUnBind
*/
publicvoidonCreate(){
MyService.onCreate"
super.onCreate();
publicintonStartCommand(Intentintent,intflags,intstartId){
MyService.onStartCommand"
returnsuper.onStartCommand(intent,flags,startId);
publicvoidonDestroy(){
MyService.onDestroy"
super.onDestroy();
publicbooleanonUnbind(Intentintent){
MyService.onUnbind"
returnsuper.onUnbind(intent);
}
(二)在AndroidManifest中注册服务
<
(三)设计控制服务开启、停止、绑定、解绑状态的代码
importandroid.content.ComponentName;
importandroid.content.ServiceConnection;
importandroid.os.Bundle;
importandroid.support.v7.app.AppCompatActivity;
importandroid.view.View;
/**
*服务的创建和使用
*注意这里的服务不依赖于Activity页面,即使页面关闭了,服务没有主动去停止,是不会关闭的
*Service也是在主线程中执行任务的,但是为什么不会造成主线程阻塞?
?
*因为做的不是耗时操作,如果做耗时操作一样会造成ANR。
。
*这里点击绑定服务后,点击停止服务按钮是无效的,要先解绑后,才能停止服务。
*正常情况下,从绑定状态到解绑状态是不会停止服务的。
只是一种状态改变而已。
*这里点击绑定服务后,点击停止服务按钮是无效的,但是解绑后,会马上停止服务。
publicclassMainActivityextendsAppCompatActivity{
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//开启服务
publicvoidstartService(Viewview){
//开启服务需要Intent对象,和Activity跳转类似
startService(newIntent(this,MyService.class));
//停止服务
publicvoidstopService(Viewview){
//停止服务的方法
stopService(newIntent(this,MyService.class));
//绑定服务
publicvoidbindService(Viewview){
bindService(newIntent(this,MyService.class),conn,flags);
//解绑服务
publicvoidunBindService(Viewview){
//防止在没有绑定的情况下,去解除绑定,抛出异常
try{
//解除绑定
unbindService(conn);
}catch(Exceptione){
MainActivity.unBindService"
+e);
//服务绑定的连接对象
privateServiceConnectionconn=newServiceConnection(){
publicvoidonServiceConnected(ComponentNamename,IBinderservice){
publicvoidonServiceDisconnected(ComponentNamename){
};
//服务绑定的标识
//BIND_AUTO_CREATE绑定的同时,启动Service
privateintflags=Service.BIND_AUTO_CREATE;
上面是使用四个按钮来实现服务的几种状态的改变。
(四)布局文件的设计
?
xmlversion="
1.0"
encoding="
utf-8"
>
LinearLayoutxmlns:
android="
android:
id="
@+id/activity_main"
layout_width="
match_parent"
layout_height="
orientation="
vertical"
TextView
wrap_content"
layout_gravity="
center_horizontal"
text="
Service"
Button
onClick="
startService"
启动服务"
stopService"
停止服务"
bindService"
绑定服务"
unBindService"
解绑服务"
/LinearLayout>
上面布局文件代码比较简单的,只是用四个按钮搞定!
程序运行后显示的界面:
这里执行了两个回调方法,先启动服务,再绑定服务!
在绑定服务的情况下是不能停止服务的,要解绑服务才能停止服务。
在程序的服务启动/绑定了的情况下,再点击启动服务,只会回调onStartCommand方法,也就是说一个服务在一个生命周期内只会回调一次onCreate方法。
点击“解绑服务”按钮后显示的Log信息:
执行了两个回调方法:
onUnBind和onDestroy
如果是用服务做简单的事情,使用第一种方法来启动服务就可以了,但是如果需要涉及到比较复杂的数据处理和操作就用绑定服务的方法来启动服务。
四.IntentService的使用示例
程序设计:
查找手机SD卡中的所有图片显示在UI界面上。
(一)布局文件activity_main.xml文件实际
RelativeLayoutxmlns:
ListView
@+id/main_lv"
/ListView>
/RelativeLayout>
非常简单的布局设计,使用ListView来显示所有的图片
(二)遍历文件的工具类的设计
packagecom.lwz.intentservice;
importandroid.os.Environment;
importandroid.os.StatFs;
importjava.io.File;
importjava.util.ArrayList;
importjava.util.List;
/**
*SD卡的路径:
Environment.getExternalStorageDirectory()
publicclassFileUtils{
*获得指定目录下的所有的图片
publicstaticfinalArrayList<
File>
getAllPicture(Filedir){
ArrayList<
files=getAllFile(dir);
imgList=newArrayList<
();
for(Filefile:
files){
if(file.getName().endsWith("
.png"
)||file.getName().endsWith("
.jpg"
))
imgList.add(file);
returnimgList;
*递归遍历文件夹的方法
publicstaticfinalvoidgetFileFromDir(Filedir,List<
fileList){
File[]files=dir.listFiles();
if(files==null)
return;
if(file.isDirectory())
getFileFromDir(file,fileList);
fileList.add(file);
}
*获得根目录下的所有图片
getAllPicture(){
returngetAllPicture(Environment.getExternalStorageDirectory());
(三)简化BaseAdapter的一个工具类
importandroid.content.Context;
importandroid.widget.BaseAdapter;
*这是一个简化BaseAdapter适配器的工具类
*这是使用的是定义一个泛型T,使用时传入什么数据,T就是什么数据
*实际设计中除了getVIew方法外,其他的方法基本是差不多的
*所以继承这个工具类后只要重写getView方法,就可以使用BaseAdapter了
publicabstractclassListItemAdapter<
T>
extendsBaseAdapter{
List<
list=newArrayList<
Contextcontext;
ListItemAdapter(Contextcontext,List<
list){
this.context=context;
this.list=list;
ListItemAdapter(Contextcontext,T[]list){
for(Tt:
this.list.add(t);
publicintgetCount(){
returnlist==null?
0:
list.size();
publicTgetItem(intposition){
null:
list.get(position);
publiclonggetItemId(intposition){
ret