Android服务Service使用总结资料.docx

上传人:b****4 文档编号:3824897 上传时间:2022-11-25 格式:DOCX 页数:25 大小:248.93KB
下载 相关 举报
Android服务Service使用总结资料.docx_第1页
第1页 / 共25页
Android服务Service使用总结资料.docx_第2页
第2页 / 共25页
Android服务Service使用总结资料.docx_第3页
第3页 / 共25页
Android服务Service使用总结资料.docx_第4页
第4页 / 共25页
Android服务Service使用总结资料.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

Android服务Service使用总结资料.docx

《Android服务Service使用总结资料.docx》由会员分享,可在线阅读,更多相关《Android服务Service使用总结资料.docx(25页珍藏版)》请在冰豆网上搜索。

Android服务Service使用总结资料.docx

Android服务Service使用总结资料

Android服务Service使用总结

一.Service简介

Service是Android系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能页面显示只能后台运行,并且可以和其他组件进行交互。

service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的,例如,一个service可能处理网络事物,播放音乐,执行文件I/O,或与一个内容提供者交互,所有这些都在后台进行。

我们一定要知道的是这里Service的后台运行并不是子线程。

Service的运行是在主线程中进行的,只是它没有界面显示而已,它的耗时操作同样需要开启子线程,否者会跟Activity一样出现ANR(applicationnotresponse–程序没有响应)。

我们要知道的是主线程的内容包括UI和后台。

只要程序中的UI或后台其中一个在跑,程序都算是在运行状态。

(一)Service的创建和注册

1.Service服务的创建

必须要实现重写其中的onBind方法,可以在里面做各种操作,也可以接收传递过来的Intent的数据做处理。

publicclassMyServiceextendsService{

@Nullable

@Override

publicIBinderonBind(Intentintent){

System.out.println("MyService.onBind");

returnnull;

}

}

2.Service服务的注册,在AndroidManifest中注册

name=".MyService"/>

服务的注册是四大组件中最简单的一个,一般只要设置name属性就可以了。

但是如果有其他需求还是要设置其他的属性值的。

对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的回调方法的顺序是:

–>onCreate()–>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

*/

publicclassMyServiceextendsService{

@Nullable

@Override

publicIBinderonBind(Intentintent){

System.out.println("MyService.onBind");

returnnull;

}

@Override

publicvoidonCreate(){

System.out.println("MyService.onCreate");

super.onCreate();

}

@Override

publicintonStartCommand(Intentintent,intflags,intstartId){

System.out.println("MyService.onStartCommand");

returnsuper.onStartCommand(intent,flags,startId);

}

@Override

publicvoidonDestroy(){

System.out.println("MyService.onDestroy");

super.onDestroy();

}

@Override

publicbooleanonUnbind(Intentintent){

System.out.println("MyService.onUnbind");

returnsuper.onUnbind(intent);

}

}

(二)在AndroidManifest中注册服务

name=".MyService"/>

(三)设计控制服务开启、停止、绑定、解绑状态的代码

packagecom.lwz.service;

importandroid.app.Service;

importandroid.content.ComponentName;

importandroid.content.Intent;

importandroid.content.ServiceConnection;

importandroid.os.Bundle;

importandroid.os.IBinder;

importandroid.support.v7.app.AppCompatActivity;

importandroid.view.View;

/**

*服务的创建和使用

*注意这里的服务不依赖于Activity页面,即使页面关闭了,服务没有主动去停止,是不会关闭的

*Service也是在主线程中执行任务的,但是为什么不会造成主线程阻塞?

*因为做的不是耗时操作,如果做耗时操作一样会造成ANR。

*这里点击绑定服务后,点击停止服务按钮是无效的,要先解绑后,才能停止服务。

*正常情况下,从绑定状态到解绑状态是不会停止服务的。

只是一种状态改变而已。

*这里点击绑定服务后,点击停止服务按钮是无效的,但是解绑后,会马上停止服务。

*/

publicclassMainActivityextendsAppCompatActivity{

@Override

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){

System.out.println("MainActivity.unBindService"+e);

}

}

//服务绑定的连接对象

privateServiceConnectionconn=newServiceConnection(){

@Override

publicvoidonServiceConnected(ComponentNamename,IBinderservice){

}

@Override

publicvoidonServiceDisconnected(ComponentNamename){

}

};

//服务绑定的标识

//BIND_AUTO_CREATE绑定的同时,启动Service

privateintflags=Service.BIND_AUTO_CREATE;

}

上面是使用四个按钮来实现服务的几种状态的改变。

(四)布局文件的设计

xmlversion="1.0"encoding="utf-8"?

>

android="

android:

id="@+id/activity_main"

android:

layout_width="match_parent"

android:

layout_height="match_parent"

android:

orientation="vertical">

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

layout_gravity="center_horizontal"

android:

text="Service"/>

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

onClick="startService"

android:

text="启动服务"/>

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

onClick="stopService"

android:

text="停止服务"/>

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

onClick="bindService"

android:

text="绑定服务"/>

android:

layout_width="wrap_content"

android:

layout_height="wrap_content"

android:

onClick="unBindService"

android:

text="解绑服务"/>

上面布局文件代码比较简单的,只是用四个按钮搞定!

程序运行后显示的界面:

这里执行了两个回调方法,先启动服务,再绑定服务!

在绑定服务的情况下是不能停止服务的,要解绑服务才能停止服务。

在程序的服务启动/绑定了的情况下,再点击启动服务,只会回调onStartCommand方法,也就是说一个服务在一个生命周期内只会回调一次onCreate方法。

点击“解绑服务”按钮后显示的Log信息:

执行了两个回调方法:

onUnBind和onDestroy

如果是用服务做简单的事情,使用第一种方法来启动服务就可以了,但是如果需要涉及到比较复杂的数据处理和操作就用绑定服务的方法来启动服务。

四.IntentService的使用示例

程序设计:

查找手机SD卡中的所有图片显示在UI界面上。

(一)布局文件activity_main.xml文件实际

xmlversion="1.0"encoding="utf-8"?

>

android="

android:

id="@+id/activity_main"

android:

layout_width="match_parent"

android:

layout_height="match_parent">

android:

id="@+id/main_lv"

android:

layout_width="match_parent"

android:

layout_height="match_parent">

非常简单的布局设计,使用ListView来显示所有的图片

(二)遍历文件的工具类的设计

packagecom.lwz.intentservice;

importandroid.os.Environment;

importandroid.os.StatFs;

importjava.io.File;

importjava.util.ArrayList;

importjava.util.List;

/**

*SD卡的路径:

Environment.getExternalStorageDirectory()

*/

publicclassFileUtils{

/**

*获得指定目录下的所有的图片

*/

publicstaticfinalArrayListgetAllPicture(Filedir){

ArrayListfiles=getAllFile(dir);

ArrayListimgList=newArrayList<>();

for(Filefile:

files){

if(file.getName().endsWith(".png")||file.getName().endsWith(".jpg"))

imgList.add(file);

}

returnimgList;

}

/**

*递归遍历文件夹的方法

*/

publicstaticfinalvoidgetFileFromDir(Filedir,ListfileList){

File[]files=dir.listFiles();

if(files==null)

return;

for(Filefile:

files){

if(file.isDirectory())

getFileFromDir(file,fileList);

fileList.add(file);

}

}

/**

*获得根目录下的所有图片

*/

publicstaticfinalArrayListgetAllPicture(){

returngetAllPicture(Environment.getExternalStorageDirectory());

}

}

(三)简化BaseAdapter的一个工具类

packagecom.lwz.intentservice;

importandroid.content.Context;

importandroid.widget.BaseAdapter;

importjava.util.ArrayList;

importjava.util.List;

/**

*这是一个简化BaseAdapter适配器的工具类

*这是使用的是定义一个泛型T,使用时传入什么数据,T就是什么数据

*实际设计中除了getVIew方法外,其他的方法基本是差不多的

*所以继承这个工具类后只要重写getView方法,就可以使用BaseAdapter了

*/

publicabstractclassListItemAdapterextendsBaseAdapter{

Listlist=newArrayList<>();

Contextcontext;

ListItemAdapter(Contextcontext,Listlist){

this.context=context;

this.list=list;

}

ListItemAdapter(Contextcontext,T[]list){

this.context=context;

for(Tt:

list){

this.list.add(t);

}

}

@Override

publicintgetCount(){

returnlist==null?

0:

list.size();

}

@Override

publicTgetItem(intposition){

returnlist==null?

null:

list.get(position);

}

@Override

publiclonggetItemId(intposition){

ret

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

当前位置:首页 > 求职职场 > 笔试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1