专栏首页向治洪Android四大组件之Service

Android四大组件之Service

Android四大组件之Service

服务的两种开启方式:

  1. startService();开启服务. 开启服务后 服务就会长期的后台运行,即使调用者退出了.服务仍然在后台继续运行.服务和调用者没有什么关系, 调用者是不可以访问服务里面的方法.
  2. bindService();绑定服务. 服务开启后,生命周期与调用者相关联.调用者挂了,服务也会跟着挂掉.不求同时生,但求同时死.调用者和服务绑定在一起,调用者可以间接的调用到服务里面的方法.

AIDL

本地服务:服务代码在本应用中 远程服务:服务在另外一个应用里面(另外一个进程里面) aidl: android interface defination language IPC implementation : inter process communication

服务混合调用的生命周期

开启服务后再去绑定服务然后再去停止服务,这时服务是无法停止了.必须先解绑服务然后再停止服务,在实际开发中会经常采用这种模式, 开启服务(保证服务长期后台运行) –> 绑定服务(调用服务的方法) –> 解绑服务(服务继续在后台运行) –> 停止服务(服务停止),服务只会被开启一次, 如果已经开启后再去执行开启操作是没有效果的。

绑定服务调用方法的原理

  1. 定义一个接口,里面定义一个方法
public interface IService {
	public void callMethodInService();//通过该类中提供一个方法,让自定 
义的类实现这个接口
}
  1. 在服务中自定义一个IBinder的实现类,让这个类继承Binder(Binder是IBinder的默认适配器),由于这个自定义类是私有的,为了其他类中能拿到该类, 我们要定义一个接口,提供一个方法,让IBinder类去实现该接口,并在相应方法中调用自己要供别人调用的方法。
 public class TestService extends Service {
	@Override
	public IBinder onBind(Intent intent) {
		System.out.println("onbind");
		return new MyBinder();
	}
	
	private class MyBinder extends Binder implements IService{
		public void callMethodInService(){
			//实现该方法,去调用服务中的方法
			methodInService();
		}
	}
	//服务中的方法
	public void methodInService(){
		Toast.makeText(this, "我是服务里面的春哥,巴拉布拉!", 0).show();
	}
}
  1. 服务的调用类中将onServiceConnected方法中的第二个参数强转成接口
public class DemoActivity extends Activity {
	private Intent intent;
	private Myconn conn;
	private IService iService;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		intent = new Intent(this,TestService.class);
		setContentView(R.layout.main);
	}
	public void start(View view) {
		startService(intent);
	}
	public void stop(View view) {
		stopService(intent);
	}
	public void bind(View view) {
		conn = new Myconn();
		//1.绑定服务 传递一个conn对象.这个conn就是一个回调接口
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}
	public void unbind(View view) {
		unbindService(conn);
	}
	//调用服务中的方法
	public void call(View view){
		iService.callMethodInService();
	}
	private class Myconn implements ServiceConnection{
		//当服务被成功绑定的时候调用的方法.
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {//第二个参数就是服务中的onBind方法的返回值
			iService = (IService) service;
		}
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
	}
}

远程服务aidl

上面介绍了绑定服务调用服务中方法的原理,对于远程服务的绑定也是这样, 但是这个远程服务是在另外一个程序中的,在另外一个程序中定 义的这个接口, 在另外一个程序中是拿不到的,就算是我们在自己的应用 中也定义一个一模一样 的接口,但是由于两个程序的报名不同,这两个接口也是不一样的,为了解决这个 问题,谷歌的工程师给提供了aidl,我们将定义的这个接口的.java改成 .aidl, 然后将这个接口中的权限修饰符去掉,在另一个程序中拷贝这个aidl文 件,然后放到同一个包名中,由于Android中通过包名来区分应用程序,这两个 aidl的包名一样,系统会认为两个程序中的接口是同一个,这样就能够在另一 个程序中将参数强转成这个接口,在使用aidl文件拷贝到自己的工程之后会自动 生成一个接口类,这个接口类中有 一个内部类Stub该类继承了Binder并实现了 这个接口,所以我们在自定义 IBinder的实现类时只需让自定义的类继承Stub类 即可.

  1. 远程服务中定义一个接口,改成aidl
package com.seal.test.service;
interface IService {
	 void callMethodInService();
}
  1. 远程服务中定义一个Ibinder的实现类,让这个实现类继承上面接口的Stub类, 并在onBind方法中返回这个自定义类对象
 public class RemoteService extends Service {
	@Override
	public IBinder onBind(Intent intent) {
		System.out.println("远程服务被绑定");
		return new MyBinder();
	}
	private class MyBinder extends IService.Stub{
		@Override
		public void callMethodInService() {
			methodInService();
		}
	}
	public void methodInService(){
		System.out.println("我是远程服务里面的方法");
	}
}
  1. 在其他程序中想要绑定这个服务并且调用这个服务中的方法的时候首先要拷贝 这个aidl文件到自己的工程,然后再ServiceConnection的实现类中将这个参数使 用asInterface方法转成接口,通过这样来得到接口,从而调用接口中的方法
public class CallRemoteActivity extends Activity {
	private Intent service;
	private IService iService;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		service = new Intent();
		service.setAction("com.itheima.xxxx");
	}
	public void bind(View veiw){
		bindService(service, new MyConn(), BIND_AUTO_CREATE);
	}
	public void call(View view){
		try {
			iService.callMethodInService();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	private class MyConn implements ServiceConnection{
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			iService = IService.Stub.asInterface(service);
		}
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
		}
	}
}

最后说一下IntentService:

IntentServiceService的子类,用来处理异步请求。客户端可以通过startService(Intent)方法将请求的Intent传递请求给IntentServiceIntentService会将该Intent加入到队列中,然后对每一个Intent开启一个worker thread来进行处理,执行完所有的工作之后自动停止Service。 每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程。IntentService 实际上是LooperHandlerService 的集合体, 他不仅有服务的功能,还有处理和循环消息的功能.

  • Service:
    1. A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
    2. A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors). 所以在Service中进行耗时的操作时必须要新开一个线程。

至于为什么要使用Service而不是Thread,这个主要的区别就是生命周期不同,Service是Android系统的一个组件,Android系统会尽量保持Service的长期后台运行, 即使内存不足杀死了该服务(很少会出现内存不足杀死服务的情况)也会在内存可用的时候去复活该服务,而Thread随后都会被杀死

  • IntentService
    1. IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests throughstartService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
    2. This “work queue processor” pattern is commonly used to offload tasks from an application’s main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
    3. All requests are handled on a single worker thread – they may take as long as necessary (and will not block the application’s main loop), but only one request will be processed at a time.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • aidl使用采坑记

    什么是AIDL? AIDL是 Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言...

    xiangzhihong
  • 23种设计模式

    一、设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:...

    xiangzhihong
  • 桥接模式

    概述 当一个抽象对象可能有多个 实现时,通常用继承来协调他们。抽象类定义对该抽象的接口,而具体的子类则用不同的方式来实现。但是此方法有时候不太灵活。继承机制将抽...

    xiangzhihong
  • JavaSE学习总结(四)——Java面向对象十分钟入门

    面向对象编程(Object Oriented Programming,OOP)是一种计算机模拟人类的自然思维方式的编程架构技术,解决了传统结构化开发方法中客观...

    张果
  • 抽象工厂模式

    ?原文地址为https://www.cnblogs.com/haixiang/p/12055272.html,转载请注明出处!

    海向
  • Android学习--探究服务(二)

          定义服务: 我们需要先创建服务,我们要使用就的利用一个类去继承它,然后重写它的几个方法,具体的我们看下面的代码:

    Mr.RisingSun
  • aidl使用采坑记

    什么是AIDL? AIDL是 Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言...

    xiangzhihong
  • Android设计模式二

    在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。

    爱因斯坦福
  • Java设计模式之模板方法模式

    假设我们现在要造一批悍马汽车,悍马汽车有两个系列H1和H2,首先不考虑任何设计模式,看看设计的类图:

    CoderJed
  • 抽象工厂模式

    抽象工厂中 接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。 在简单工厂中,我们需要一辆车就用CarFact...

    OPice

扫码关注云+社区

领取腾讯云代金券