常用在’下载’操作。
说明:bindService()启动的服务,是将活动与服务绑定,只要没有解绑定,服务就会一直保持运行状态。
之前的服务,只是启动了服务,就让服务运行了,至于操作了什么,活动并不知道,如果想要活动去自会服务区干什么就需要用到onBind()方法。
1>服务中创建一个Binder类的子类,并创建实例。onBind()方法返回这个实例即可。子类中提供了一些查看服务的方法。
2>活动中创建ServiceConnection类的子类的实例,这里面其实可以获得binder实例。
3>可以在点击事件中绑定服务:
bindService(intent,connection,标志位);
普通服务:
1)创建服务类,继承Service类:
2)注册服务。(四大组件的共同性,都需要在配置文件中进行注册)
3)在活动中启动或停止服务。
创建服务类,继承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是自定义的服务类。
启动服务:
关闭服务:
效果演示:
当内存不足时,后台的服务很可能被回收,如果希望服务一直保持运行,考虑前台服务。
特殊之处:会在状态栏一直显示运行图标。
在自定义的服务类中,创建通知Notification;最后用startForefround()方法接收两个参数,第一个:是通知的id,第二个:创建的Notification对象。
如果需要详细介绍,请自行查看API
Service服务开启后,如果没有停止就会一直进行,为了可以创建一个异步、可自动停止的服务,android推出IntentService
与Service类似:
1>自定义服务类继承IntentService.
注:
其中必须提供一个无参的构造函数,必须在内部调用父类的有参构造函数。
public class MyIntentService extends IntentService {
public MyIntentService() {
super("yyyyyyyyyyy");
}
实现onHandleIntent()抽象方法,
2>配置文件中进行注册。
1)使用时自定义的类中需要添加一个无参构造器;
/* 活动启动服务,服务在后台进行下载,这里用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中停止线程即可。
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();
}
}