【发布时间】:2019-09-02 08:33:09
【问题描述】:
我是一名从 Java 切换到 Kotlin 的 Android 开发人员,我打算使用协程来处理异步代码,因为它看起来很有前途。
回到 Java 中,为了处理异步代码,我使用 Executor 类在远离 UI 线程的另一个线程中执行一段耗时的代码。我有一个AppExecutors 类,我将它注入我的xxxRepository 类来管理一组Executor。它看起来像这样:
public class AppExecutors
{
private static class DiskIOThreadExecutor implements Executor
{
private final Executor mDiskIO;
public DiskIOThreadExecutor()
{
mDiskIO = Executors.newSingleThreadExecutor();
}
@Override
public void execute(@NonNull Runnable command)
{
mDiskIO.execute(command);
}
}
private static class MainThreadExecutor implements Executor
{
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
@Override
public void execute(@NonNull Runnable command)
{
mainThreadHandler.post(command);
}
}
private static volatile AppExecutors INSTANCE;
private final DiskIOThreadExecutor diskIo;
private final MainThreadExecutor mainThread;
private AppExecutors()
{
diskIo = new DiskIOThreadExecutor();
mainThread = new MainThreadExecutor();
}
public static AppExecutors getInstance()
{
if(INSTANCE == null)
{
synchronized(AppExecutors.class)
{
if(INSTANCE == null)
{
INSTANCE = new AppExecutors();
}
}
}
return INSTANCE;
}
public Executor diskIo()
{
return diskIo;
}
public Executor mainThread()
{
return mainThread;
}
}
然后我就可以在我的xxxRepository 中编写一些这样的代码:
executors.diskIo().execute(() ->
{
try
{
LicensedUserOutput license = gson.fromJson(Prefs.getString(Constants.SHAREDPREF_LICENSEINFOS, ""), LicensedUserOutput.class);
/**
* gson.fromJson("") returns null instead of throwing an exception as reported here :
* https://github.com/google/gson/issues/457
*/
if(license != null)
{
executors.mainThread().execute(() -> callback.onUserLicenseLoaded(license));
}
else
{
executors.mainThread().execute(() -> callback.onError());
}
}
catch(JsonSyntaxException e)
{
e.printStackTrace();
executors.mainThread().execute(() -> callback.onError());
}
});
它工作得非常好,谷歌甚至在他们的许多 Github Android repo 示例中都有类似的东西。
所以我使用了回调。但现在我厌倦了嵌套回调,我想摆脱它们。为此,我可以写在我的xxxViewModel 中,例如:
executors.diskIo().execute(() ->
{
int result1 = repo.fetch();
String result2 = repo2.fetch(result1);
executors.mainThread().execute(() -> myLiveData.setValue(result2));
});
USAGE 与 Kotlin 协程的用法有何不同?据我所见,他们最大的优势是能够以顺序代码风格使用异步代码。但是我可以使用Executor 做到这一点,正如您从上面的代码示例中看到的那样。
那么我在这里缺少什么?从Executor 切换到协程我会得到什么?
【问题讨论】:
标签: java android kotlin coroutine kotlin-coroutines