Service 理解和两种启动方式

Service 理解和两种启动方式

Service 理解

Service是什么?

Service 作为android系统的四大组件之一,是一种可以在后台长时间运行操作而没有用户界面的应用组件。

Service和Thread的区别

1、Thread是程序运行的最小单位即线程,可以执行异步长时间耗时的操作。

2、Service是android中的组件,是运行在主线程上的,是要依托android程序运行的,所以不能做耗时操作。

Service android是四大组件之一。Service 是一个抽象类,我们需要些一个自定义Service继承于Service。

启动方式

Service 的启动方式有两种,一种是startService(),一种是bindService().这两种方式有有什么区别.

startService(),启动完之后该service就在后台运行,其生命周期跟启动它的Context没有任何关系。也不能跟Context通讯。

bindService()启动之后生命周期跟启动它的Context有关,比如Activity、fragment、service等。在Context中解绑之后,如果改Service没有任何绑定后该Service也就结束。

生命周期

Service 的生命周期跟启动方式有关。

stratService的生命周期: onCreate() -> onStartCommand() -> onDestroy()

startService.png

bindService的生命周期: onCreate() -> onBind() -> onUnbind() -> onDestroy()

bindservice.png

startService

用startService 方式启动Service的时候重写onStartCommand()的方法。每次用该方式启动Service的时候都会调用改方法。

返回值是一个int类型的:

START_STICKY: 当Service因内存不足而被系统kill后,一段时间后内存再次空闲时,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand方法,但其中的Intent将是null,除非有挂起的Intent,如pendingintent,这个状态下比较适用于不执行命令、但无限期运行并等待作业的媒体播放器或类似服务。

START_NOT_STICKY:当Service因内存不足而被系统kill后,即使系统内存再次空闲时,系统也不会尝试重新创建此Service。除非程序中再次调用startService启动此Service,这是最安全的选项,可以避免在不必要时以及应用能够轻松重启所有未完成的作业时运行服务。

START_REDELIVER_INTENT:当Service因内存不足而被系统kill后,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand(),任何挂起 Intent均依次传递。

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

String test = intent.getStringExtra("test");

LogHelper.i("-------test-------" + test);

LogHelper.i("-------flags-------" + flags);

LogHelper.i("-------startId-------" + startId);

LogHelper.i("-------onStartCommand-------");

return super.onStartCommand(intent, flags, startId);

}

这里的参数是:

intent: 启动时,启动组件传递过来的Intent,如Activity可利用Intent封装所需要的参数并传递给Service。

flags: 表示启动请求时是否有额外数据,可选值有 0,START_FLAG_REDELIVERY,START_FLAG_RETRY,0代表没有.START_FLAG_REDELIVERY: 这个值代表了onStartCommand方法的返回值为START_REDELIVER_INTENT,意味着当Service因内存不足而被系统kill后,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。START_FLAG_RETRY : 该flag代表当onStartCommand调用后一直没有返回值时,会尝试重新去调用onStartCommand()。

startId:指明当前服务的唯一ID,与stopSelfResult (int startId)配合使用,stopSelfResult 可以更安全地根据ID停止服务。

startService的完整Service:

public class SimpleService extends Service {

/**

* 绑定服务时才会调用,必须要实现的方法

* @param intent

* @return

*/

@Nullable

@Override

public IBinder onBind(Intent intent) {

return null;

}

/**

* Called by the system when the service is first created.

* 首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。

* 如果服务已在运行,则不会调用此方法。该方法只被调用一次

*/

@Override

public void onCreate() {

super.onCreate();

LogHelper.i("-------onCreate-------");

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

String test = intent.getStringExtra("test");

LogHelper.i("-------test-------" + test);

LogHelper.i("-------flags-------" + flags);

LogHelper.i("-------startId-------" + startId);

LogHelper.i("-------onStartCommand-------");

return super.onStartCommand(intent, flags, startId);

}

/**

* 服务销毁时的回调

*/

@Override

public void onDestroy() {

LogHelper.i("-------onDestroy-------");

super.onDestroy();

}

}

调用也就是简单的startService:

mStart.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(ServiceActivity.this,SimpleService.class);

intent.putExtra("test","数据传输");

startService(intent);

}

});

mEnd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(ServiceActivity.this,SimpleService.class);

stopService(intent);

}

});

bindService

bindService 的方式启动Service,其作用是该Service可以和启动它的Context(Activity等)进行通讯。其是ServiceConnection()的接口方法和服务器交互,在绑定即onBind()的时候回调。在这个方法中获取Service传递过来的IBinder对象,通过这个对象实现跟宿主交互。

BindService的Service:

public class BindService extends Service {

private LocalBinder mBinder = new LocalBinder();

private Thread mThread;

private int count;

@Nullable

@Override

public IBinder onBind(Intent intent) {

LogHelper.i("------onBind-----");

return mBinder;

}

@Override

public void onCreate() {

super.onCreate();

LogHelper.i("------onCreate-----");

mThread = new Thread(new Runnable() {

@Override

public void run() {

while (true){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

count++;

}

}

});

mThread.start();

}

@Override

public int onStartCommand(Intent intent,int flags, int startId) {

return super.onStartCommand(intent, flags, startId);

}

@Override

public void onDestroy() {

super.onDestroy();

LogHelper.i("------onDestroy-----");

}

@Override

public boolean onUnbind(Intent intent) {

LogHelper.i("------onUnbind-----");

return super.onUnbind(intent);

}

public int getCount(){

return count;

}

/**

* 创建Binder对象,为后面给绑定的Activity使用。

*/

public class LocalBinder extends Binder {

/**

* 提供一个方法,返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了

* @return

*/

BindService getService(){

return BindService.this;

}

}

}

调用的方式:先创建ServiceConnection:

mConn = new ServiceConnection(){

/**

* 与服务器端交互的接口方法 绑定服务的时候被回调,在这个方法获取绑定Service传递过来的IBinder对象,

* 通过这个IBinder对象,实现宿主和Service的交互。

*/

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

LogHelper.i("---绑定成功.---");

BindService.LocalBinder binder = (BindService.LocalBinder)service;

mBindService = binder.getService();

}

/**

* 当取消绑定的时候被回调。但正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时,

* 例如内存的资源不足时这个方法才被自动调用。

*/

@Override

public void onServiceDisconnected(ComponentName name) {

LogHelper.i("---取消绑定.---");

mBindService = null;

}

};

//绑定启动Service.

mStart.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(BindServiceActivity.this,BindService.class);

bindService(intent,mConn, Service.BIND_AUTO_CREATE);

}

});

//解绑Service

mEnd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if(mBindService != null){

mBindService = null;

unbindService(mConn);

}

}

});

//通过IBinder获取Service对象,然后访问Service的public方法。

mGet.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if(mBindService != null){

int count = mBindService.getCount();

LogHelper.i("-------count--------" + count);

mText.setText("---" + count);

}else {

LogHelper.i("-------service 未绑定--------");

}

}

});

区别

调用方式不同;

startService

使用Service的步骤:

1.定义一个类继承Service

2.在Manifest.xml文件中配置该Service

3.使用Context的startService(Intent)方法启动该Service

4.不再使用时,调用stopService(Intent)方法停止该服务

使用这种start方式启动的Service的生命周期如下:

onCreate()--->onStartCommand()(onStart()方法已过时) ---> onDestory()

说明:如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()。

服务停止的时候调用 onDestory()。服务只会被停止一次。

特点:一旦服务开启跟调用者(开启者)就没有任何关系了。开启者退出了,开启者挂了,服务还在后台长期的运行。开启者不能调用服务里面的方法。

bindService

使用Service的步骤:

1.定义一个类继承Service

2.在Manifest.xml文件中配置该Service

3.使用Context的bindService(Intent, ServiceConnection, int)方法启动该Service

4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务作者:

使用这种start方式启动的Service的生命周期如下:

onCreate() --->onBind()--->onunbind()--->onDestory()

注意:绑定服务不会调用onstart()或者onstartcommand()方法

特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。

绑定者可以调用服务里面的方法。

相关推荐

眼膜贴多久时间合适
365bet手机版下载

眼膜贴多久时间合适

📅 07-05 👁️ 495
佳能EF 28-300mm f/3.5-5.6L IS评测
365bet手机版下载

佳能EF 28-300mm f/3.5-5.6L IS评测

📅 06-29 👁️ 5751
狸窝DVD刻录软件:全中文界面,适合新手,支持视频直接刻录(无需预先转换格式)
任我花怎么借钱?任我花借款步骤?
mobile365体育投注官网

任我花怎么借钱?任我花借款步骤?

📅 07-02 👁️ 2600
眼膜贴多久时间合适
365bet手机版下载

眼膜贴多久时间合适

📅 07-05 👁️ 495
巴珑(2008年广西师范大学出版社出版的图书)
mobile365体育投注官网

巴珑(2008年广西师范大学出版社出版的图书)

📅 07-02 👁️ 3741
22x22等于多少
365bet手机版下载

22x22等于多少

📅 06-30 👁️ 8006
打开尘封的记忆 世界杯经典照片集你还记得吗
Bet体育365第二次提款要多久

打开尘封的记忆 世界杯经典照片集你还记得吗

📅 06-30 👁️ 8034
Android(安卓)手机变砖复活的三种恢复方法
mobile365体育投注官网

Android(安卓)手机变砖复活的三种恢复方法

📅 06-28 👁️ 1613