Android Service 启动方式,生命周期和应用场景详解

Android Service 启动方式,生命周期和应用场景详解

第一种方式:通过StartService启动Service(特点:不管启动多少次,只需要执行一次stopService即可关闭服务)

通过startService启动后,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。

要创建一个这样的Service,你需要让该类继承Service类,然后重写以下方法:

onCreate()1.如果service没被创建过,调用startService()后会执行onCreate()回调;2.如果service已处于运行中,调用startService()不会执行onCreate()方法。也就是说,onCreate()只会在第一次创建service时候调用,多次执行startService()不会重复调用onCreate(),此方法适合完成一些初始化工作。

onStartCommand() ------》其中有四种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后一定能重启。如果多次执行了Context的startService()方法,那么Service的onStartCommand()方法也会相应的多次调用。onStartCommand()方法很重要,我们在该方法中根据传入的Intent参数进行实际的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。

onBind()Service中的onBind()方法是抽象方法,Service类本身就是抽象类,所以onBind()方法是必须重写的,即使我们用不到。

onDestory()在销毁的时候会执行Service该方法。

这几个方法都是Service的回调方法,且在主线程中执行。

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

第二种方式:通过bindService启动Service

bindService启动服务特点:(和小程序一样,一次性滴,进入页面的时候绑定service,退出的时候关闭service)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会自行销毁。

bindService代码实例

1.创建一个FinnService继承Service(Server)

/**

* Created by Finn on 2019-10-10.

*/

public class bindServiceA extends Service{

//client 可以通过Binder获取Service实例

public class MyBinder extends Binder {

public bindService getService() {

return bindServiceA .this;

}

}

//通过binder实现调用者client与Service之间的通信 在onBind中返回该对象

private MyBinder binder = new MyBinder();

private final Random generator = new Random();

@Override

public void onCreate() {

Log.i("Finn","bindServiceA - onCreate - Thread = " + Thread.currentThread().getName());

super.onCreate();

}

@Override

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

Log.i("Finn", "bindServiceA - onStartCommand - startId = " + startId + ", Thread = " + Thread.currentThread().getName());

return START_NOT_STICKY;

}

@Nullable

@Override

public IBinder onBind(Intent intent) {

Log.i("Finn", "bindServiceA - onBind - Thread = " + Thread.currentThread().getName());

return binder;

}

@Override

public boolean onUnbind(Intent intent) {

Log.i("Finn", "bindService - onUnbind - from = " + intent.getStringExtra("from"));

return false;

}

@Override

public void onDestroy() {

Log.i("Finn", "bindServiceA - onDestroy - Thread = " + Thread.currentThread().getName());

super.onDestroy();

}

//getRandomNumber是Service暴露出去供client调用的公共方法

public int getRandomNumber() {

return generator.nextInt();

}

2.创建ActivityA,可以通过bindService绑定服务(client)

public class ActivityA extends Activity {

private bindServiceA service = null;

private boolean isBind = false;

private ServiceConnection conn = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder binder) {

isBind = true;

bindService .MyBinder myBinder = (bindServiceA.MyBinder) binder;

service = myBinder.getService();//通过ServiceConnection 中的IBinder获取 绑定的service对象

Log.i("Finn", "ActivityA - onServiceConnected");

int num = service.getRandomNumber();//通过service对象可对 bindServiceA中的函数进行操作

Log.i("Kathy", "ActivityA - getRandomNumber = " + num);

}

@Override

public void onServiceDisconnected(ComponentName name) {

isBind = false;

Log.i("Finn", "ActivityA - onServiceDisconnected");

}

};

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_a);

Log.i("Finn", "ActivityA - onCreate - Thread = " + Thread.currentThread().getName());

bindservice();

unbindservice();

}

private void bindservice(){

Intent intent = new Intent(this, bindServiceA.class);

intent.putExtra("from", "ActivityA");

Log.i("Finn", "ActivityA 执行 bindServiceA");

bindService(intent, conn, BIND_AUTO_CREATE);//通过该方法绑定服务(周期:onCreate()------》onbind())

}

private void unbindservice(){

//单击了“unbindService”按钮

if (isBind) {

Log.i("Finn", "ActivityA 执行 unbindService");

unbindService(conn);//通过该方法解除绑定服务 周期:----先执行 onunbind()---》onDestroy()

}

}

@Override

protected void onDestroy() {

super.onDestroy();

Log.i("Finn", "ActivityA - onDestroy");

}

}

bindServices创建如下:要想让Service支持bindService调用方式,需要做以下事情:1.在Service的onBind()方法中返回IBinder类型的实例。2.onBInd()方法返回的IBinder的实例需要能够返回Service实例本身。通常,最简单的方法就是在service中创建binder的内部类,加入类似getService()的方法返回Service,这样绑定的client就可以通过getService()方法获得Service实例了。

🖌️ 相关文章

小天鹅TG70-1229EDS
365天电影观看免费

小天鹅TG70-1229EDS

📅 06-29 👁️ 9595
Qt 在Qwidget里添加控件
365bet在线娱

Qt 在Qwidget里添加控件

📅 06-28 👁️ 7456