一. SPI即Service Provider Interfaces
.
有时候一个接口可能有多种实现方式, 如果将特定实现写死在代码里面, 那么要更换实现的时候就要改动代码, 对原有代码进行重写. 这样非常麻烦, 而且也容易导致bug. Java提供了一种方式, 让我们可以对接口的实现进行动态替换, 这就是SPI机制. SPI机制非常简单, 步骤如下:
- 定义接口
- 定义接口的实现
- 创建resources/META-INF/services目录
- 在上一步创建的目录下创建一个以接口名(类的全名) 命名的文件, 文件的内容是实现类的类名 (类的全名), 如:
- 在services目录下创建的文件是
com.stone.imageloader.ImageLoader
文件中的内容为ImageLoader接口的实现类, 可能是com.stone.imageloader.impl.FrescoImageLoader
- 使用ServiceLoader查找接口的实现.
spi机制将接口和实现分开, 方便实现的动态替换. 这就是面向接口编程, 其好处是显而易见的.
二. Android App应用也是用Java编写的, 因此SPI在Android中同样是可以使用的.
Android上使用SPI的步骤和Java中是一样的. 下面给出实例:
- (1) 创建spi接口, 如下:
package com.stone.image.spi;
public interface ImageLoader {
void displayImage();
}
- (2) 实现spi接口, 如下:
package com.stone.image.spi.impl;
import android.util.Log;
import com.stone.image.spi.ImageLoader;
public class FrescoImageLoader implements ImageLoader {
@Override
public void displayImage() {
Log.e("_fresco_", this.getClass().getName() + " - displayImage: Hello world !");
}
}
(3) 创建目录
resources/META-INF/services
目录-
(4) 创建以接口命名的文件(
com.stone.image.spi.ImageLoader
), 内容为接口的实现类. 下面是spi的描述文件:
(5) 使用ServiceLoader动态查找接口的实现并使用.
下面是在Activity中查找接口的实现, 并调用接口的方法, 代码如下:
public class SpiActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spi);
findViewById(R.id.spi_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//下面调用方式都ok
// ServiceLoader<ImageLoader> serviceLoader = ServiceLoader.load(ImageLoader.class);
// ServiceLoader<ImageLoader> serviceLoader = ServiceLoader.load(ImageLoader.class, this.getClass().getClassLoader());
ServiceLoader<ImageLoader> serviceLoader = ServiceLoader.load(ImageLoader.class, ImageLoader.class.getClassLoader());
Iterator<ImageLoader> it = serviceLoader.iterator();
if (it.hasNext()) {
it.next().displayImage();
}
}
});
}
}
点击按钮会输出下面信息:
com.stone.image.spi.impl.FrescoImageLoader - displayImage: Hello world !
关于spi在Android中的使用场景, 大家可以自己发掘 。◕‿◕。 .......