一、创建Service
第一种方式:通过StartService启动Service
通过startService启动后,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。
要创建一个这样的Service,你需要让该类继承Service类,然后重写以下方法:
-
onCreate()
1.如果service没被创建过,调用startService()后会执行onCreate()回调;
2.如果service已处于运行中,调用startService()不会执行onCreate()方法。
也就是说,onCreate()只会在第一次创建service时候调用,多次执行startService()不会重复调用onCreate(),此方法适合完成一些初始化工作。 -
onStartCommand()
如果多次执行了Context的startService()方法,那么Service的onStartCommand()方法也会相应的多次调用。onStartCommand()方法很重要,我们在该方法中根据传入的Intent参数进行实际的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。 -
onBind()
Service中的onBind()方法是抽象方法,Service类本身就是抽象类,所以onBind()方法是必须重写的,即使我们用不到。 -
onDestory()
在销毁的时候会执行Service该方法。
这几个方法都是回调方法,且在主线程中执行,由android操作系统在合适的时机调用。
使用这种start方式启动的Service的生命周期如下:onCreate()
--->onStartCommand()
(onStart()
方法已过时) ---> onDestory()
说明:如果服务已经开启,不会重复的执行onCreate()
, 而是会调用onStart()
和onStartCommand()
。
服务停止的时候调用 onDestory()
。服务只会被停止一次。
特点:一旦服务开启跟调用者(开启者)就没有任何关系了。
开启者退出了,开启者挂了,服务还在后台长期的运行。
开启者不能调用服务里面的方法。
startService代码实例
创建TestOneService,并在manifest里注册。
在MainActivty中操作TestOneService,code如下:
public class TestOneService extends Service{
@Override
public void onCreate() {
Log.i("Kathy","onCreate - Thread ID = " + Thread.currentThread().getId());
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Kathy", "onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().getId());
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("Kathy", "onBind - Thread ID = " + Thread.currentThread().getId());
return null;
}
@Override
public void onDestroy() {
Log.i("Kathy", "onDestroy - Thread ID = " + Thread.currentThread().getId());
super.onDestroy();
}
}
第二种方式:通过bindService启动Service
bindService启动服务特点:
1.bindService启动的服务和调用者之间是典型的client-server模式。调用者是client,service则是server端。service只有一个,但绑定到service上面的client可以有一个或很多个。这里所提到的client指的是组件,比如某个Activity。
2.client可以通过IBinder接口获取Service实例,从而实现在client端直接调用Service中的方法以实现灵活交互,这在通过startService方法启动中是无法实现的。
3.bindService启动服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。当然,client也可以明确调用Context的unbindService()方法与Service解除绑定。当没有任何client与Service绑定时,Service会自行销毁。
使用Service的步骤:
1.定义一个类继承
Service
2.在Manifest.xml
文件中配置该Service
3.使用Contex
t的bindService(Intent, ServiceConnection, int)
方法启动该Service
4.不再使用时,调用unbindService(ServiceConnection)
方法停止该服务
使用这种start方式启动的Service的生命周期如下:onCreate()
--->onBind()
--->onunbind()
--->onDestory()
注意:绑定服务不会调用onstart()
或者onstartcommand()
方法
特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。
绑定者可以调用服务里面的方法。
二、调用
绑定本地服务调用方法的步骤:
- 在服务的内部创建一个内部类 提供一个方法,可以间接调用服务的方法
- 实现服务的onbind方法,返回的就是这个内部类
- 在activity 绑定服务。bindService();
- 在服务成功绑定的回调方法onServiceConnected, 会传递过来一个 IBinder对象
- 强制类型转化为自定义的接口类型,调用接口里面的方法。
首先定义一个Service
的子类
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
//返回MyBind对象
return new MyBinder();
}
private void methodInMyService() {
Toast.makeText(getApplicationContext(), "服务里的方法执行了。。。",
Toast.LENGTH_SHORT).show();
}
/**
* 该类用于在onBind方法执行后返回的对象,
* 该对象对外提供了该服务里的方法
*/
private class MyBinder extends Binder implements IMyBinder {
@Override
public void invokeMethodInMyService() {
methodInMyService();
}
}
}
自定义的MyBinder
接口用于保护服务中不想让外界访问的方法。
public interface IMyBinder {
void invokeMethodInMyService();
}
接着在Manifest.xml
文件中配置该Service
<service android:name=".MyService"/>
绑定服务的Activity:
public class MainActivity extends Activity {
private MyConn conn;
private Intent intent;
private IMyBinder myBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//开启服务按钮的点击事件
public void start(View view) {
intent = new Intent(this, MyService.class);
conn = new MyConn();
//绑定服务,
// 第一个参数是intent对象,表面开启的服务。
// 第二个参数是绑定服务的监听器
// 第三个参数一般为BIND_AUTO_CREATE常量,表示自动创建bind
bindService(intent, conn, BIND_AUTO_CREATE);
}
//调用服务方法按钮的点击事件
public void invoke(View view) {
myBinder.invokeMethodInMyService();
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//iBinder为服务里面onBind()方法返回的对象,所以可以强转为IMyBinder类型
myBinder = (IMyBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
}