Service详解
Android四大组件之一,Service 是长期运行在后台的应用程序组件。Service 不是进程,也不是线程,它和应用程序在同一个进程中,Service中不能做耗时操作,运行在主线程中。主要应用与后台播放音乐,定位服务,每隔一定时间和服务器进行交互。注意service需要在注册列表中注册!
一、定义
Android四大组件之一,是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件。服务能够被其他组件启动、绑定、交互、通信。
二、基本类型
1、Started(启动)
通过startService()方法启动的Service。通常,started的服务执行单一的操作并且不会向调用者返回结果。
2、Bound(绑定)
通过bindService()方法绑定的Service。bound服务提供了一个客户端/服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至可以利用进程间通信(IPC)跨进程执行这些操作。绑定服务的生存期和被绑定的应用程序组件一致。 多个组件可以同时与一个服务绑定,不过所有的组件解除绑定后,服务也就会被销毁。
注:服务运行于宿主进程的主线程中,耗时操作需要新建线程。
子线程中使用会崩溃,例如,在onclick中,加入一个Thread线程实现setTextView("string"),这种方式会导致任务程序崩溃。
三、Service的生命周期
Service有两种启动方式,生命周期不一样:
- onCreate()->onStartCommand()->onDestory()
- onCreate()->onBind()->onUnbind()->onDestory()
1、onCreate() 注意一个activityA跳转到activity后,A中的服务终止
首次创建服务时,系统将调用此方法来执行一次性设置程序,在调用 onStartCommand() 或 onBind() 之前。如果服务已在运行,则不会调用此方法。
2、onStartCommand()
通过调用 startService() 请求启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。通过调用 stopSelf() 或 stopService() 来停止服务。
3、onBind()
通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。
4、onUnbind()
当Service上绑定的所有客户端都断开连接时调用此方法。
5、onDestroy()
当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。 这是服务接收的最后一个调用。
注意事项:
1.Service不是一个单独的进程 ,它和应用程序在同一个进程中。
2.Service不是一个线程,所以我们应该避免在Service里面进行耗时的操作
注意服务是被动在acitivty中启动的
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private Button startServiceBtn;
private Button stopServideBtn;
private Button goBtn;
private Button unBindServiveBtn;
private Intent serviceIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startServiceBtn = (Button) findViewById(R.id.start_service);
stopServideBtn = (Button) findViewById(R.id.stop_service);
goBtn = (Button) findViewById(R.id.go);
unBindServiveBtn = (Button)findViewById(R.id.unbind) ;
startServiceBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
serviceIntent = new Intent(MainActivity.this, HelloService.class); // HelloService
startService(serviceIntent); //启动服务
}
});
stopServideBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(serviceIntent);
}
});
goBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, BActivity.class);
startActivity(intent);
}
});
}
HelloService代码:
public class HelloService extends Service{
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i("onCreate", "首次创建服务");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.i("onBind", "服务绑定");
return onBind(intent);
}
// 已经废弃
// @Override
// @Deprecated
// public void onStart(Intent intent, int startId) {
// super.onStart(intent, startId);
// }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i("onStartCommand", "服务即会启动并可在后台无限期运行");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.i("onUnbind", " 当Service上绑定的所有客户端都断开连接时调用此方法。");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.i("onDestroy", "当服务不再使用且将被销毁时,系统将调用此方法");
super.onDestroy();
}
}
Intent service简介
这是 Service 的子类,它使用工作线程逐一处理所有启动请求。如果您不要求服务同时处理多个请求,这是最好的选择。 您只需实现 onHandleIntent() 方法即可,该方法会接收每个启动请求的 Intent,使您能够执行后台工作。 有以下特点:
1、IntentService会创建单独的Worker线程处理所有的Intent请求;
2、IntentService会创建单独的worker线程来处理onHandleIntent()方法实现的代码,因此无需处理多线程问题;
3、所有请求处理完成后,IntentService自动停止。无需调用stopSelf()方法停止该Service;
4、service的onBind()方法提供了默认实现,返回null;
5、service的onStartCommand()方法提供了默认实现,该实现会将请求Intent添加到队列中。
使用方法:扩展IntentService重写onHandlerIntent()方法。
举例如下:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService"); // 调用父类的有参构造函数
}
@Override
protected void onHandleIntent(Intent intent) {
// 打印当前线程的id
Log.d("MyIntentService", "Thread id is " + Thread.currentThread(). getId());
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyIntentService", "onDestroy executed");
}
}
注意:Intent service 方法也是需要在activity中引用的,但是可以在点击事件中引用该类型服务
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); // 启动服务
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); // 停止服务
break;
case R.id.bind_service:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务
break;
case R.id.unbind_service:
unbindService(connection); // 解绑服务
break;
/** 这里实现的intentService服务 **/
case R.id.start_intent_service:
// 打印主线程的id
Log.d("MainActivity", "Thread id is " + Thread.currentThread(). getId());
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);
break;
default:
break;
}
}
参考学习: