第十五天·Service服务
Service的生命周期
Service是安卓的四大组件之一,用于长时间驻留在后台进行操作
注意:他区别于线程,虽然是在APP中进行创建和绑定的,但是最终是在主线程里运行的
所以,一些耗时的操作,例如:网络请求,用户输入,音视频播放等,最好是在Service的子线程中进行处理
Service生命周期:
Service有两种启动方式:
一种是startService():onCreate()--》onStart()-》ServiceRunning--》
(如果调用context.stopService())--》onDestory()--》ServiceShutdown
如果在程序运行期间,又调用了StartService(),那么这个时候就不走onCreate()方法,而是直接走onStart()方法
一种是BindService():onCreate()--》onBind()--》ServiceRunning--》onUnbind()--》onDestory()--》ServiceStop
和上面的一样,如果运行期间调用了BindService(),那么这个时候会走onBind方法,而不走onCreate()。
区别:onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法。比如得到Service运行的状态和其他操作
这个时候调用者和Service是绑定在一起的,Context退出了,Service就会调用onUnBind()--》onDestory()进行退出。
也就是说BindService()会把Service和Activity进行绑定,一旦Activity销毁,那么对应的服务也就销毁了,但是按Home键不会消失
Service的启动方式有两种
context.startService();
context.bindService();
启动方式的区别:
用context.startService()方法启动的服务,Service与Context相互的关联并不大,相当于只是Context仅仅通知了一下Service可以启动了
而Context.bindService()方法启动的Service与Context之间关联比较密切,Context可以指定Service执行某些任务.
简单实现一个Service
1、创建一个MyService类来继承Service,添加其生命周期的方法,打印Log,
2、在Manifest.xml里注册service
<service android:name=".MyService">
<!--这个是进行服务启动时候的过滤的,启动指定的服务-->
<intent-filter>
<action android:name="com.xiaogao.serviceDemo" />
</intent-filter>
</service>
3、然后再在MainActivity里添加监听点击事件,调用startService方法启动服务
startService(new Intent(MyService.ACTION));
stopService方法停止服务
stopService(new Intent(MyService.ACTION));
bindService方法绑定服务
Intent intent=new Intent(MyService.ACTION);
bindService(intent,sc,BIND_AUTO_CREATE);
unbindService方法解除绑定
Intent intent=new Intent(MyService.ACTION);
unbindService(sc);
绑定服务bindService方法里的第二参数的创建
ServiceConnection sc=new ServiceConnection(){
//当与服务器连接的时候
public void onServiceConnected(ComponentName componentName,IBinder IBinder){
Log.i("输出","context与服务绑定成功");
MyService.SimpleBinder binder= (MyService.SimpleBinder) iBinder;
Log.i("输出","从服务中获取数据为:"+binder.getService());
}
//当与服务器断开的时候
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("输出","context与服务解绑成功");
}
4、在MyService里添加的方法
声明SimpleBinder binder;
onCreate()–》new binder
onStartCommand()
onBind()–》return binder;
onDestroy()
onUnbind()
然后再在MyService里头创建一个SimpleBinder内部类
class SimpleBinder extends Binder{
//这里的方法就是自定义的方法,用来实现服务的逻辑思维
//模拟从服务中获取数据
public String getService(){
return "你获取数据一个";
}
然后在回到MainActivity里上午ServiceConnection调用一下getService的方法
MyService.SimpleBinder binder= (MyService.SimpleBinder) iBinder;
Log.i("输出","从服务中获取数据为:"+binder.getService());
注意
1、你应当注意 使用 startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;
2、同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
3、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
4、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。
源码在此:
package com.xiaogao.user.android2lesson_15_service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button startService;
private Button bindService;
private Button stopService;
private Button unbindService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService= (Button) findViewById(R.id.main_start_service);
startService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//调用方法启动服务
startService(new Intent(MyService.ACTION));
}
});
//停止服务
stopService= (Button) findViewById(R.id.main_stop_service);
stopService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(new Intent(MyService.ACTION));
}
});
//绑定服务
bindService= (Button) findViewById(R.id.main_bind_service);
bindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//调用方法,绑定服务
Intent intent=new Intent(MyService.ACTION);
//第一个参数是intent,第二个参数是: 第三个参数是一个标志位,定值BIND_AUTO_CREATE
bindService(intent,sc,BIND_AUTO_CREATE);
}
});
unbindService= (Button) findViewById(R.id.main_unbind_service);
unbindService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent =new Intent(MyService.ACTION);
unbindService(sc);
}
});
}
ServiceConnection sc=new ServiceConnection() {
//当与服务器连接的时候
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("输出","context与服务绑定成功");
MyService.SimpleBinder binder= (MyService.SimpleBinder) iBinder;
Log.i("输出","从服务中获取数据为:"+binder.getService());
}
//当与服务器断开的时候
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("输出","context与服务解绑成功");
}
};
}
MyService.class
package com.xiaogao.user.android2lesson_15_service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
//1、创建一个Service类继承Service,添加其方法,打印log
//2、在Manifest.xml里注册service
//3、然后再在MainActivity里添加点击事件
public class MyService extends Service {
public final static String ACTION="com.xiaogao.serviceDemo";
private SimpleBinder binder;
@Override
public void onCreate() {
super.onCreate();
binder=new SimpleBinder();
Log.i("周期","onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("周期","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("输出","onBind");
return binder;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("周期","onDestroy");
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("输出","onUnBind");
return super.onUnbind(intent);
}
class SimpleBinder extends Binder{
//这里的方法就是自定义的方法,用来实现服务的逻辑思维
//模拟从服务中获取数据
public String getService(){
return "你获取数据一个";
}
//*****onBindService进行数据频繁的交流
//Service也可提供了两个方法进行音乐控制,一个是播放,一个是暂停,下一首
}
}