常用在’下载’操作。
1.概述:
2. 生命周期:
说明:bindService()启动的服务,是将活动与服务绑定,只要没有解绑定,服务就会一直保持运行状态。
3.onBind()活动和服务进行通信
1)概述:
之前的服务,只是启动了服务,就让服务运行了,至于操作了什么,活动并不知道,如果想要活动去自会服务区干什么就需要用到onBind()方法。
2)用到的类:
1>服务中创建一个Binder类的子类,并创建实例。onBind()方法返回这个实例即可。子类中提供了一些查看服务的方法。
2>活动中创建ServiceConnection类的子类的实例,这里面其实可以获得binder实例。
3>可以在点击事件中绑定服务:
bindService(intent,connection,标志位);
4.使用步骤:
普通服务:
1)创建服务类,继承Service类:
2)注册服务。(四大组件的共同性,都需要在配置文件中进行注册)
3)在活动中启动或停止服务。
5.范例:
创建服务类,继承Service类:
public class MyService extends Service {
/**
* 重写onCreate()和onStartCommand()方法
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("service", "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d("service", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d("service", "onDestroy");
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
注册服务:
其中的MyService是自定义的服务类。
启动服务:
关闭服务:
效果演示:
6.其他用法:
1).使用前台服务:
@1.概述;
当内存不足时,后台的服务很可能被回收,如果希望服务一直保持运行,考虑前台服务。
特殊之处:会在状态栏一直显示运行图标。
@2.用法:
在自定义的服务类中,创建通知Notification;最后用startForefround()方法接收两个参数,第一个:是通知的id,第二个:创建的Notification对象。
如果需要详细介绍,请自行查看API
2).IntentService:(运行结束自动回收)
@1.概述:
Service服务开启后,如果没有停止就会一直进行,为了可以创建一个异步、可自动停止的服务,android推出IntentService
@2.用法:
与Service类似:
1>自定义服务类继承IntentService.
注:
其中必须提供一个无参的构造函数,必须在内部调用父类的有参构造函数。
public class MyIntentService extends IntentService {
public MyIntentService() {
super("yyyyyyyyyyy");
}
实现onHandleIntent()抽象方法,
2>配置文件中进行注册。
@3.与普通服务Service的区别:
- Service:
运行在主线程中,启动服务后,其中一定要有子线程去处理耗时操作。
第一次启动时,服务调用 - IntentService:
自身包含了一个线程;
包含了一个消息队列,第一次启动,调用onHandleIntent(Intent intent )方法,以后再重复启动,就将所有进来的intent存到消息列表中,等待处理,所以IntentService并不是多线程处理。
@4.注意:
1)使用时自定义的类中需要添加一个无参构造器;
7.范例:service模拟下载
/* 活动启动服务,服务在后台进行下载,这里用count–来模拟,由于别的线程无法操作UI(这个在线程中讲),将count值通过广播发给活动,由主线程来绘制UI。注:不要忘了服务注册 */
public class MyDownloadService extends Service{
private int count=0;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {//创建子线程,返回count值给主线程(通过发送广播)
// TODO Auto-generated method stub
Log.d("message", "线程要开始");
new Thread(new Runnable() {
public void run() {
Intent intent = new Intent();
intent.setAction(MainActivity.FLAG);
while(count<100)
{
//Log.d("message", count+"");
count++;
intent.putExtra("count", count);
sendBroadcast(intent);
try {
Thread.sleep(200);//休眠一段时间,写到while循环中
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
解析:
自定义的服务子类,重写onStartCommand方法,在其中创建一个线程,用于count–,并将值放在intent中,发送广播给主线程。
动态注册广播
接收广播
启动和关闭服务。
总结:
广播:需要注册,发送和接收;
服务:需要自定义服务子类,注册,启动和停止。
问题:点击关闭时,服务关闭了,但线程并未关闭,所以如果要停止下载还要停止线程。在onDestroy中停止线程即可。
效果演示:
利用IntentService:
public class MyIntentService extends IntentService{
private int count;
public MyIntentService(){
super("");
}
public MyIntentService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
protected void onHandleIntent(Intent arg0) {
// TODO Auto-generated method stub
Log.d("message", "进入IntentService");
Intent intent = new Intent();
intent.setAction(MainActivity.FLAG);
while(count<100)
{
count++;
intent.putExtra("count", count);
sendBroadcast(intent);
try {
Thread.sleep(200);//休眠一段时间,写到while循环中
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.d("message", "IntentService已经onDestroy");
super.onDestroy();
}
}
效果演示:
可以看出与service的区别:当下载完成后,自动运行onDestroy()方法。