Service简介
Service是Android四大组件之一,它用来在后台完成一个时间跨度比较大的工作并且没有关联任何界面。
Service能干些什么
- 访问网络
- 播放音乐
- 文件IO操作
- 大数据量的数据库操作
- ......
声明周期
Service声明周期
- onCreate() :
首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次,后面在启动服务时,服务只执行onStartCommand()。 - onStartCommand():
当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。 - onBind():
当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。 - onUnbind():
当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。 - onDestroy():
当服务不再使用且将被销毁时,系统将调用此方法。
开启和停止Service
1.第一次启动服务: startService() --- onCreate() --- onStartCommand()
2.第n次点击启动服务: onStartCommand() (n > 1)
3.第一次点击停止服务: stopService() --- onDestroy()
4.第n次点击停止服务:没有任何调用 (n > 1)
绑定和解绑Service
1.第一次绑定服务:bindService() --- onCreate() --- onBind() --- onServiceConnected()
2.第n次绑定服务:onServiceConnected() (n > 1)
3.第一次解绑服务:onUnBind() ---- onDestroy()
4.第n次解绑服务: 无响应
特点
- Service在后台运行,不用与用户进行交互
- 即使程序别切换到后台、或者用户打开新的应用,服务仍可运行
- 服务并非运行在独立的进程中,而是依赖于服务创建的应用程序进程,如果此应用进程被杀掉,该服务也会停止。
- 在默认情况下,Service运行在应用程序进程的主线程(UI线程)中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在分线程中处理,避免阻塞用户界面而导致ANR
Service与Activity区别?
1.Activity:
- Activity对应一个界面
- 应用退出,Activity对象就会死亡
- 应用再次进入,启动的Activity对象时重新创建的
2.Service:
- 不与任何界面关联,绝不会到前台来
- 应用退出,Service仍在运行
- 应用再次进入,启动的Service还是前面运行的Service对象
3.Activity与Service的选择标准:
- 如果某个应用程序组件需要运行时向用户呈现某种界面,或者改程序需要与用户进行交互,那么就用Activity,否则用Service
Service与Thread的区别
1.Service
- 用来在后台完成一个时间跨度比较大的工作的应用组件
- Service的生命周期方法运行在主线程,如果Service想做持续时间比较长的工作,需要启动一个分线程(Thread)
- 应用退出后Service不会停止
- 应用再次进入,可以与正在运行的Service进行通信
2.Thread
- 用来开启一个分线程的类,做一个长时间的工作
- Thread对象的run()在分线程执行
- 应用退出:Thread不会停止
- 应用再次进入,不能再控制前面启动的Thread对象
创建一个Service服务
public class MyService extends Service {
public MyService(){
Log.e("TAG", "MyService()");
}
@Override
public IBinder onBind(Intent intent) {
Log.e("TAG", "onBind()--绑定服务--data="+ intent.getStringExtra("data"));
return new Binder();
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("TAG", "onUnbind()--解绑服务");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
Log.e("TAG", "onCreate()--创建服务");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("TAG", "onStartCommand()--启动服务,data = " + intent.getStringExtra("data"));
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.e("TAG", "onDestroy()--销毁服务");
super.onDestroy();
}
}
创建一个Activity来调用服务
public class MainActivity extends Activity {
// 提供一个ServiceConnection
private ServiceConnection conn = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//开启服务
public void startMyService(View v) {
// 对于本地服务,使用一个显示意图即可
Intent intent = new Intent(MainActivity.this, MyService.class);
// 开启一个服务
intent.putExtra("data", "我是数据");
startService(intent);
}
//停止服务
public void stopMyService(View v) {
// 对于本地服务,使用一个显示意图即可
Intent intent = new Intent(MainActivity.this, MyService.class);
// 停止一个服务
stopService(intent);
}
// ************上下分别对应着启动并操作服务的两种方式******************
// 绑定服务
public void bindMyService(View v) {
if (conn == null) {
conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("TAG", "onServiceDisconnected");
}
// 只有绑定的服务中的onBind()方法返回值不为空时,此方法才会调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("TAG", "onServiceConnected");
}
};
// 对于本地服务,使用一个显示意图即可
Intent intent = new Intent(MainActivity.this, MyService.class);
intent.putExtra("data", "我是数据");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}else{
Log.e("TAG", "已经绑定了服务");
}
}
// 解绑服务
public void unbindMyService(View v) {
if(conn != null){
// 解绑服务
unbindService(conn);
conn = null;//conn必须要置空
Log.e("TAG", "unbindMyService()");
}
}
//确保在Activity销毁之前将已经绑定的Service解绑
@Override
protected void onDestroy() {
if(conn != null){
// 解绑服务
unbindService(conn);
}
super.onDestroy();
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1. 测试启动本地服务"
android:textSize="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startMyService"
android:text="启动服务" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="stopMyService"
android:text="停止服务" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2. 测试绑定本地服务"
android:textSize="25sp"
android:layout_marginTop="10dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="bindMyService"
android:text="绑定服务" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="unbindMyService"
android:text="解绑服务" />
</LinearLayout>
</LinearLayout>
Service的分类
-
Local Service(本地服务)
Service对象与Service的启动者在同个进程中运行,两者的通信是进程内通信 -
Remote Service(远程服务)
Service对象与Service的启动者不在同一个进程中运行,这时存在一个进程间通信的问题,Android专门为此设计了ALDL来实现进程间通信













网友评论