Retrofit
能在Android
上,实现子线程接口请求,主线程回调,是因为Retrofit
内部有一个Platform
类,判断当前运行的平台是Android环境时,创建Platform
的子类Android
,复写defaultCallbackExecutor
方法,实现主线程执行器即可。
总体来说,因为Retrofit
良好的设计,只要改动1个类,就可以让Retrofit适配Harmony鸿蒙
。如果你使用RxJava
,则可以使用鸿蒙专属适的Scheduler
调度器来实现线程切换。详情见Harmony鸿蒙 专属RxHarmony
因为Retrofit
的Platform
类的平台判断是写死在findPlatform()
方法中的,所以需要拷贝Retrofit
的源码,再进行修改适配,是比较麻烦的。
其实,Retrofit
可以把Platform
再做一层责任链,支持动态添加Platfrom实现,或者在Retrofit.Builder
中支持手动指定自定义Platform
子类,即可动态支持多平台,期待后续Retrofit可以完善吧~
如果对Retrofit的源码感兴趣,可以看这篇Retrofit 源码分析
进行适配
class Platform {
/**
* 单例,查找到后,后续再调用不会再次查找
*/
private static final Platform PLATFORM = findPlatform();
/**
* 获取Platform实例的方法
*/
static Platform get() {
return PLATFORM;
}
/**
* 查找当前平台的实现
*/
private static Platform findPlatform() {
try {
Class.forName("ohos.system.version.SystemVersion");
//Harmony鸿蒙
if (SystemVersion.getApiVersion() != 0) {
return new Harmony();
}
} catch (ClassNotFoundException ignored) {
//ignored
}
try {
Class.forName("android.os.Build");
//安卓
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
//ignored
}
//Java8
return new Platform(true);
}
//省略无关代码
static final class Harmony extends Platform {
Harmony() {
//鸿蒙运行在Java8上
super(true);
}
@Override
public Executor defaultCallbackExecutor() {
//回调时使用的执行器,回调在主线程
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
/**
* 鸿蒙主线程执行器
*/
static final class MainThreadExecutor implements Executor {
private final EventHandler handler = new EventHandler(EventRunner.getMainEventRunner());
@Override
public void execute(Runnable task) {
handler.postTask(task);
}
}
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
/**
* 安卓主线程执行器
*/
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable task) {
handler.post(task);
}
}
}
}
网友评论