AutoApi
通过注解实现模块组件化的一个框架
最新版本
模块 | autoapi | autoapi-plugin | autoapi_process |
---|---|---|---|
最新版本 | 1.1.0 | 1.1.0 | 1.1.0 |
一、功能介绍
- 支持通过注解自动生成接口工程代码
- 支持静态 public 方法和普通 public 方法
- 通过注解构造函数和静态方法,支持多构造函数接口实例创建
- 支持服务方法泛型
- 支持方法自定义参数生成 api 类替换,避免参数类型下沉
- 支持 callback 参数类型
- 支持提供父类 public 方法
- 支持 EventBus 通信
- 提供开关,关闭 api 工程代码自动生成
二、应用场景
- 业务模块分离,实现组件化的通信方式,解耦、接口(非协议)方式通信
- 跨模块工程之间 EventBus 通信
三、功能使用
1. SDK 引入
-
提供接口服务的原 module 工程配置
- apiProjectPath:当前工程对应的接口工程路径
- packageName:当前工程对应的接口工程包名
- apiBuildEnable:编译期是否重新生成接口工程代码
- logOpen:编译期代码生成逻辑,是否打开本地日志
apply plugin: 'android-aspectjx' repositories { maven { url 'https://raw.githubusercontent.com/bitterbee/mvn-repo/master/' } } android { defaultConfig { javaCompileOptions { annotationProcessorOptions { def path = "${rootProject.projectDir}/${接口工程文件夹名}".toString() arguments = [apiProjectPath: path, packageName: "${接口工程包名}", apiBuildEnable: "true", logOpen: "true"] } } } } dependencies { compile 'com.netease.libs:autoapi:1.1.0' compile 'com.netease.libs:autoapi-api:1.1.0' annotationProcessor 'com.netease.libs:autoapi_process:1.1.0' compileOnly 'org.aspectj:aspectjrt:1.8.9' }
-
接口工程配置
配置生成
api_records/${packagename}.records.txt
文件,支持接口工程 clean 操作。 每次编译生成接口工程代码时,在${packagename}.records.txt
文件记录接口类,clean 操作的时候,对照接口工程源码和 records.txt,删除真正需要删除的接口类clean.doLast { def recordDir = file("${project.projectDir}/api_records/") if (!recordDir.exists() || !recordDir.directory) { return } def contents = new ArrayList<String>() for (File recordFile : recordDir.listFiles()) { if (recordFile.exists() && !recordFile.directory) { def text = recordFile.text if (text != null && !text.empty) { contents.add(recordFile.text) } } } if (contents.empty) { return } def sourcePath = "${project.projectDir}/src/main/java/" def sourceDir = file(sourcePath) def records = new ArrayList<String>() for (String content : contents) { for (String r : content.split(";\\n")) { def record = r.trim() if (record != null && !record.isEmpty()) { // println "record file " + sourcePath + record records.add(sourcePath + record) } } } def removePaths = subtract(recursivlyGetFiles(sourceDir), records) for (String path : removePaths) { if (path.endsWith(".java")) { file(path).delete() println "remove file " + path } } } List<String> subtract(List<String> a, List<String> b) { if (a == null || a.empty || b == null || b.empty) { return a } def res = new ArrayList<String>(a) for (String item : b) { if (res.contains(item)) { res.remove(item) } } return res } List<String> recursivlyGetFiles(File dir) { def result = new ArrayList<String>() if (dir == null || !dir.exists() || !dir.directory) { return result } for (File sub : dir.listFiles()) { if (sub.directory) { result.addAll(recursivlyGetFiles(sub)) } else { result.add(sub.absolutePath) } } return result }
2. 框架基础使用
-
接口实现工程(app工程):
- AutoApiClassAnno 注解类指定提供接口服务类
- AutoApiMethodAnno 注解 public 方法,指定服务接口类提供的方法
@AutoApiClassAnno public class DeviceUtil { @AutoApiMethodAnno public int getDeviceId() { return 0; } }
-
接口使用工程(demomodule1):
接口工程引用:
compile project(':app-api') // 接口工程名自行制定
接口服务使用:
DeviceUtilApiFactory deviceUtilFactory = AutoApi.getApiFactory("DeviceUtilApi"); DeviceUtilApi deviceUtil = deviceUtilFactory.newInstance(); int id = deviceUtil.getDeviceId(); // id == 0
3. 框架高级使用
1. 多构造方式
-
接口实现工程(app工程):
AutoApiConstructAnno
:注解构造函数AutoApiClassBuildMethodAnno
:注解静态方法返回实例对象
@AutoApiClassAnno public class AddUtil { private int mData1 = 0; private int mData2 = 0; @AutoApiConstructAnno public AddUtil(int data1, int data2) { mData1 = data1; mData2 = data2; } @AutoApiConstructAnno public AddUtil(int data) { mData1 = data; mData2 = data; } @AutoApiClassBuildMethodAnno public static AddUtil getInstance(int data1, int data2) { return new AddUtil(data1, data2); } @AutoApiMethodAnno public int calu() { return mData1 + mData2; } }
-
接口使用工程(demomodule1):
接口服务使用:
AddUtilApiFactory factory = AutoApi.getApiFactory("AddUtilApi"); AddUtilApi api0 = factory.newInstance(11, 12); AddUtilApi api1 = factory.newInstance(3); AddUtilApi api2 = factory.getInstance(1, 2); int result0 = api0.calu(); // 23 int result1 = api1.calu(); // 6 int result2 = api1.calu(); // 3
2. 支持普通方法和静态方法
-
接口实现工程(app工程):
@AutoApiClassAnno public class Minus { private int mData1 = 0; private int mData2 = 0; @AutoApiConstructAnno public Minus(int data1, int data2) { mData1 = data1; mData2 = data2; } @AutoApiMethodAnno public int calu() { return mData1 - mData2; } @AutoApiMethodAnno public static int minus(int a, int b) { return a - b; } }
-
接口使用工程(demomodule1):
接口服务使用:
MinusApiFactory factory = AutoApi.getApiFactory("MinusApi"); MinusApi api = factory.newInstance(10, 5); int result0 = api.calu(); // 5 int result1 = api.minus(10, 5); // 5
接口类不区分是否静态方法
3. 支持单例
-
接口实现工程(app工程):
@AutoApiClassAnno public class Singleton { private static Singleton sInstance = null; @AutoApiClassBuildMethodAnno() public static Singleton getInstance() { if (sInstance == null) { synchronized (Singleton.class) { if (sInstance == null) { sInstance = new Singleton(); } } } return sInstance; } private Singleton() { } @AutoApiMethodAnno() public String foo1(String str1, String str2) { Log.i("Singleton", "foo1 called"); return str1 + "_" + str2; } }
-
接口使用工程(demomodule1):
接口服务使用:
SingletonApiFactory apiFactory = AutoApi.getApiFactory("SingletonApi"); SingletonApi singleton = apiFactory.getInstance(); String result = singleton.foo1("var1", "var2");
4. 支持自定义参数和返回值类型转换
-
接口实现工程(app工程):
@AutoApiClassAnno public class DataModelOperator { @AutoApiMethodAnno public static DataModel add(DataModel a, DataModel b) { return a == null || b == null ? null : new DataModel(a.getA() + b.getA(), a.getB() + b.getB()); } }
@AutoApiClassAnno public class DataModel { private int a; private int b; @AutoApiConstructAnno() public DataModel(int a, int b) { this.a = a; this.b = b; } public DataModel() { this.a = 0; this.b = 0; } public int getA() { return a; } public int getB() { return b; } }
生成接口类:
public interface DataModelOperatorApi extends ApiBase { DataModelApi add(DataModelApi a, DataModelApi b); }
public interface DataModelApi extends ApiBase { }
-
接口使用工程(demomodule1):
接口服务使用:
DataModelOperatorApiFactory factory = AutoApi.getApiFactory("DataModelOperatorApi"); DataModelOperatorApi api = factory.newInstance(); DataModelApiFactory dataFactory = AutoApi.getApiFactory("DataModelApi"); DataModelApi model1 = dataFactory.newInstance(4, 5); DataModelApi model2 = dataFactory.newInstance(1, 2); DataModelApi result = api.add(model1, model2);
5. callback 类型参数转换
-
接口实现工程(app工程):
- listener 参数属于回调,添加注解
AutoApiCallbackAnno
@AutoApiClassAnno(allPublicNormalApi = true) public class HttpUtil { public Request query(@AutoApiCallbackAnno HttpListener listener) { return new Request(); } }
@AutoApiClassAnno(allPublicNormalApi = true) public class Request { public void cancel() { Log.i("AutoApi", "cancel request"); } }
@AutoApiClassAnno(allPublicNormalApi = true, includeSuperApi = true) public interface HttpListener extends BaseHttpListener { void onCancel(); }
- listener 参数属于回调,添加注解
-
接口使用工程(demomodule1):
接口服务使用:
HttpUtilApiFactory factory = AutoApi.getApiFactory("HttpUtilApi"); HttpUtilApi api = factory.newInstance(); RequestApi request = api.query(new HttpListenerApi() { @Override public void onCancel() { } @Override public void onHttpSuccess(String httpName, Object result) { } @Override public void onHttpError(String httpName, int errorCode, String errorMsg) { } @Override public Object getApiServiceTarget() { return null; } }); // 根据业务场景执行请求取消操作 request.cancel();
6. 支持泛型
-
接口实现工程(app工程):
@AutoApiClassAnno public class JsonUtil { @AutoApiMethodAnno public static <T> T toJsonObj(String jsonStr, Class<T> clazz) { if (TextUtils.isEmpty(jsonStr)) { return null; } try { return JSONObject.parseObject(jsonStr, clazz, Feature.IgnoreNotMatch); } catch (Throwable e) { e.printStackTrace(); } return null; } }
-
接口工程代码 (app-api工程)
public interface JsonUtilApi extends ApiBase { <T> T toJsonObj(String jsonStr, Class<T> clazz); }
7. 支持 EventBus
-
接口实现工程(app工程):
@AutoApiClassAnno() public class EventA { }
-
接口使用工程(demomodule1):
接口服务使用:
EventAApiFactory factory = AutoApi.getApiFactory("EventAApi"); EventAApi api = factory.newInstance(); EventBus.getDefault().post(api.getApiServiceTarget());
8. 支持别名,支持导出父类接口
-
接口实现工程(app工程):
@AutoApiClassAnno(name = "CalculatorAlias", allPublicStaticApi = true, includeSuperApi = true) public class Calculator extends Adder { public static int minuse(int a, int b) { return a - b; } public static int multiply(int a, int b) { return a * b; } }
public class Adder { public static int add(int a, int b) { return a + b; } }
-
接口使用工程(demomodule1):
接口服务使用:
CalculatorAliasApiFactory factory = AutoApi.getApiFactory("CalculatorAlias"); CalculatorAlias calculator = factory.newInstance(); int add = calculator.add(1,2); // 3 int minuse = calculator.minuse(2, 1); // 1 int multiply = calculator.multiply(2,3); //6