Android中SPI的使用

原创 2017年05月10日 11:09:43

转载注明出处:http://blog.csdn.net/xiaohanluo/article/details/71515678

1. 简介

SPI全称是Service Provider Interface,服务提供方接口,服务通常是指一个接口或者一个抽象类,服务提供方是对这个接口或者抽象类的具体实现,由第三方来实现接口提供具体的服务。SPI提供了一种动态的对应用程序进行扩展的机制,通常用作框架服务的拓展或者可替换的服务组件,但是在Android中并没有广泛的使用。

SPI运用场景主要有:

官方介绍文档:https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html

2. SPI机制

  • 在resources/META-INF/services/目录中创建以服务全限定名命名的文件,该文件内容为服务的具体实现类的全限定名,文件中可以写多个服务的具体实现类
  • 使用ServiceLoader类动态加载服务的具体实现类
  • 服务具体的实现类必须有一个不带参数的构造方法
  • 如果服务的具体实现类在Jar包中,则需要放在主程序的classPath中

3. SPI的使用

SPI在Android工程中很少被使用到,主要因为SPI是针对厂商或者第三方服务商设置的机制,在平常的项目中很少会用到SPI。在业务越来越复杂的今天,很多应用趋向于组件化,项目中会依赖很多组件,这样会有一些问题,主工程和组件怎么通信,组件之间又怎么通信。当然有很多可以解决通信的方法,这里举个SPI例子。


图-1 举例示意图

主工程中依赖有三个组件,分别提供三个服务ABC,在用户切换后台后,主程序想要关闭定位,但是由于服务ABC可能对定位信息变化非常敏感,需要由服务的具体场景来告诉主程序是否能够关闭定位。

3.1 定义接口或者抽象类

定义接口

public interface IService {
    boolean keep();
}

3.2 实现接口

定义三个服务实现该接口,简化逻辑直接返回。

public class AService implements IService {
    @Override
    public boolean keep() {
        return false;
    }
}

public class BService implements IService {
    @Override
    public boolean keep() {
        return false;
    }
}

public class CService implements IService {
    @Override
    public boolean keep() {
        return true;
    }
}

3.3 创建spi描述文件

在工程的main目录下新建目录resources/META-INF/services,以服务接口名为文件名新建spi描述文件,内容为具体的服务实现类权限定名,可以有多个。


图-2 目录结构图

文件内容如下:

com.spi.demo.AService
com.spi.demo.BService
com.spi.demo.CService

3.4 调用具体服务

使用ServiceLoader去加载具体服务类,然后遍历具体的实现类,ServiceLoader其实就是去META-INFO/services目录下读取文件内容,然后实例化。

mBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ServiceLoader<IService> loader = ServiceLoader.load(IService.class);
        Iterator<IService> iterator = loader.iterator();
        boolean isKeepLoc = false;

        while (iterator.hasNext()) {
            if(iterator.next().keep()){
                isKeepLoc = true;
                break;
            }
        }

        Toast.makeText(MainActivity.this, "Keep location : " + isKeepLoc, Toast.LENGTH_SHORT).show();
    }
});

4. SPI的优点

只提供服务接口,具体服务由其他组件实现,接口和具体实现分离,同时能够通过系统的ServiceLoader拿到这些实现类的集合,统一处理。

5. SPI的缺点

  • Java中SPI是随jar发布的,每个不同的jar都可以包含一系列的SPI配置,而Android平台上,应用在构建的时候最终会将所有的jar合并,这样很容易造成相同的SPI冲突,常见的问题是DuplicatedZipEntryException异常
  • 读取SPI配置信息是在运行时从jar包中读取,由于apk是签过名的,在从jar中读取的时候,签名校验的耗时问题会造成性能损失

6. 优化思路

Java中使用ServiceLoader去读取SPI配置信息是在程序运行时,我们可以将这个读取配置信息提前,在编译时候就搞定,通过gradle插件,去扫描class文件,找到具体的服务类(可以通过标注来确定),然后生成新的java文件,这个文件中包含了具体的实现类。

这样程序在运行时,就已经知道了所有的具体服务类,缺点就是编译时间会加长,自己需要重新写一套读取SPI信息、生成java文件等逻辑。

经过优化后,SPI已经偏离了原本的初衷,但是可以做更多的事,可以将业务服务分离,通过SPI找到业务服务入口,业务组件化,抽成单独的aar,独立成工程。

7. 总结

SPI是java中原有的机制,在Android中可以直接使用,但是有上述提到的一些缺点,我们可以参考Java中的SPI机制,结合Android的环境,输出一套新的SPI机制。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android Things SDK用法之SPI篇

1.SPI 串行外设接口(SPI)设备通常都使用在要求快速的数据传输速率场景上。SPI非常适合于高带宽使用情况,如外部非易失性存储器和图形显示。许多传感器设备除了支持I2C,也支持SPI。 ...
  • ppplulu12
  • ppplulu12
  • 2017年05月11日 16:09
  • 539

spi demo code 及 使用注意事项

[DESCRIPTION]   目前比较多的外设会用到spi interface.此FAQ旨在描述spi driver的使用方法及使用过程中会遇到的问题及解决方法。     ...
  • goodtalent
  • goodtalent
  • 2015年12月22日 12:18
  • 1341

在Android上实现SPI通信之(1)------在Ubuntu12.04环境下编译android源码

在Android上实现SPI通信之(1)——在Ubuntu12.4环境下编译android源码作为一个Android应用开发者,突然接到一下需求,需要在应用层传递一个信号到外设,传递方式用SPI通信,...
  • u011514076
  • u011514076
  • 2017年05月22日 17:06
  • 266

SPI初步接触和简单例子

偶然间看到SPI这个名词,之前知道API,但是SPI还没怎么接触过,打算找些资料看看。     API和SPI的区别是啥?      API全称是Application Programming I...
  • iamzhongyong
  • iamzhongyong
  • 2013年07月11日 09:57
  • 1129

基于UCOSII的DMA-SPI通信

代码有点小bug,比如主机的dma定义长度为8位,发送8为数据为:0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08,从机第一次接收数据格式:0x01 0x02 0x03 ...
  • zhy421955124
  • zhy421955124
  • 2017年09月06日 15:56
  • 227

JDK的SPI机制

SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简...
  • u012009613
  • u012009613
  • 2016年10月07日 23:06
  • 967

Linux中SPI驱动调试总结

1.先了解一下spi协议的基本信息,包括spi的工作原理,4中不同模式的区别。 2.在调试的时候,先用示波器量一下每跟信号线的信号是否正常。    CS(片选)(平常是高电平,通信被拉低)    C...
  • mike8825
  • mike8825
  • 2016年02月28日 23:04
  • 1308

全志A20配置使用spi 功能

全志A20配置使用spi。 Yao.GUET 2014-07-17,转载请注明出处:http://blog.csdn.net/Yao_GUET A20上带有4个spi接口,由于Humm...
  • Diwat
  • Diwat
  • 2015年04月01日 14:03
  • 2236

Android Things:外设I/O接口-SPI

一、接口简介串行外围接口(Serial Peripheral Interface)设备通常需要快速的数据传输速率。SPI适合高带宽使用情况,如外部非易失性存储器和图形显示,许多传感器除了I2C也支持S...
  • p106786860
  • p106786860
  • 2017年05月02日 00:00
  • 1353

DSP28335 SPI的使用

#include "spi.h" void spi_init() { InitSpiaGpio(); //  不使用FIFO SpiaRegs.SPICCR.all =0x0007; ...
  • bood123
  • bood123
  • 2016年03月31日 16:42
  • 3679
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android中SPI的使用
举报原因:
原因补充:

(最多只允许输入30个字)