一、Service初步了解
Service是Android中四大组件之一,用来进行后台处理时间长的任务操作,可以避免Android的ANR。最为经典的使用场景是在音乐播放器中,使用Service可以使音乐在后台播放,即使我们离开播放器APP音乐也不会停止。Service+Notification+Broadcast Receive三者联合使用将会得到意想不到的用户体验。作为组件,Service需要在Manifirst.xml文件中进行注册。
想要使用Service服务必须继承android.app.Service类,主要处理其中的以下方法:
public class MyStartService extends Service {
public void onCreate() {
super.onCreate();
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
public void onDestroy() {
super.onDestroy();
}
}
二、Service的两种启动方式
1、startService():Context组件通过调用此方法可以启动一个Service,此时启动的服务不收Context组件的生命周期的影响。也就是说当启动服务的组件销毁后,服务依然存在。此时Service的生命周期相关的函数是onCreat()、onStart()、onStartCommand()、onDestory();
startService()开始服务:
stopService()停止服务:
当我们多次startService()时,onCreate()只会调用一次,而onStart()和onStartCommand()可以多次调用,不管调用多少次startService(),我们只需要使用一次stopService()就可以将服务销毁,以下是我们进行3次启动1次销毁的log日志:
2、bindService():Context组件通过调用此方法可以绑定一个Service,当启动它的组件销毁时,其绑定的服务也会一起销毁,有种爱叫做不求同生,但愿同死的赶脚。在启动组件销毁前,我们必须要保证它与绑定的服务间要有解绑动作,不然Android系统会报错误。在进行绑定时会涉及到一个ServiceConnection类,当绑定成功时会回调其中的onServiceConnected()方法。
在进行绑定服务的时候相关的生命周期方法是:onCreate()、onBind()、onUnbind()、onDestory();
bindService()绑定服务:
unBindService()解除绑定:
多次调用bindService()绑定服务时,不会重复调用生命周期函,一下是3次绑定1次解除绑定的log:
三、同时使用两种方式来启动Service服务
当我们同时使用了startService()开始服务和bindService()绑定服务时,必须调用一次stopService()和unBindService()才能够销毁一个服务。大家跟着我的操作来一起看看log日志:
操作步骤:
1、startService()开始服务
2、bindService()绑定服务
3、startService()开始服务
4、bindService()绑定服务
5、stopService()服务
6、startService()开始服务
7、startService()开始服务
8、stopService()服务
9、unBindService()服务
源代码部分:
Activity代码:
public class SjcServiceActivity extends Activity {
Intent startServiceIntent;
ServiceConnection connection;
boolean isBindService = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
startServiceIntent = new Intent(this, MyStartService.class);
connection = new ServiceConnection() {
//当绑定的服务崩溃或被杀死导致的连接中断时被调用,自己解除绑定时则不会被调用
public void onServiceDisconnected(ComponentName name) {
Log.i("TAG", "MyStartService --> onServiceDisconnected");
unBindServie();
}
//当绑定服务时会调用这个方法
public void onServiceConnected(ComponentName name, IBinder service) {
isBindService = true;
Log.i("TAG", "MyStartService --> onServiceConnected");
}
};
}
protected void onDestroy() {
super.onDestroy();
unBindServie();//当Activity销毁时,必须解除所绑定的服务,不然会报错
}
public void onClick(View v) {
Button btn = (Button)v;
switch (v.getId()) {
case R.id.btn_startService:
startService(startServiceIntent);
break;
case R.id.btn_stopService:
stopService(startServiceIntent);
break;
case R.id.btn_bindService:
bindService(startServiceIntent, connection, Context.BIND_AUTO_CREATE);
break;
case R.id.btn_unbindService:
unBindServie();
break;
default:
Toast.makeText(this, btn.getText(), Toast.LENGTH_SHORT).show();
break;
}
}
private void unBindServie() {
if(isBindService) {
isBindService = false;
unbindService(connection);
}
}
}
Activity的布局xml文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Service"
android:id="@+id/btn_startService"
android:layout_margin="5dp"
android:onClick="onClick"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop Service"
android:id="@+id/btn_stopService"
android:layout_margin="5dp"
android:onClick="onClick"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Bind Service"
android:id="@+id/btn_bindService"
android:layout_margin="5dp"
android:onClick="onClick"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Unbind Service"
android:id="@+id/btn_unbindService"
android:layout_margin="5dp"
android:onClick="onClick"
/>
</LinearLayout>
</FrameLayout>
Service代码:
public class MyStartService extends Service {
public void onCreate() {
super.onCreate();
Log.i("TAG", "MyStartService --> onCreate");
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i("TAG", "MyStartService --> onStart");
}
//在Android2.0时系统引进了onStartCommand方法取代onStart方法,
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("TAG", "MyStartService --> onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
//服务在绑定时调用,
//如果返回值为null,则不会调用ServiceConnection的onServiceConnected()方法
public IBinder onBind(Intent intent) {
Log.i("TAG", "MyStartService --> onBind");
return new Binder() {
};
}
public boolean onUnbind(Intent intent) {
Log.i("TAG", "MyStartService --> onUnbind");
return super.onUnbind(intent);
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "service destroy", Toast.LENGTH_SHORT).show();
Log.i("TAG", "MyStartService --> onDestroy");
}
}
Service在清单文件中的注册:
<service android:name="com.sjc.myproject.apis.service.MyStartService"></service>