나는 코 틀린 자바로 전환 안드로이드 개발자입니다, 나는 매우 유망한 보이는 때문에 비동기 코드를 처리하는 코 루틴을 사용할 계획입니다.
자바 돌아 가기, 내가 사용하던 비동기 코드를 처리하기 위해 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에서 안드로이드의 repo 예에서와 비슷한 있습니다.
그래서 콜백을 사용했다. 하지만 지금 나는 중첩 된 콜백의 피곤 하고 나는 그들을 제거하려는. 이렇게하려면 내에서 쓸 수 xxxViewModel
에 대한 예 :
executors.diskIo().execute(() ->
{
int result1 = repo.fetch();
String result2 = repo2.fetch(result1);
executors.mainThread().execute(() -> myLiveData.setValue(result2));
});
어떻게 즉 사용법 코 틀린의 코 루틴 '사용 다른는? 내가 본 바로는, 자신의 가장 큰 장점은 순차적 인 코드 스타일의 비동기 코드를 사용할 수있게하는 것입니다. 하지만 난 그냥 그와 함께 할 수 있어요 Executor
당신이 바로 위의 코드 샘플에서 볼 수 있습니다. 그래서 여기에 무엇을 놓치고? 나는 무엇으로 전환하는 얻을 것이다 Executor
코 루틴에?
내 응용 프로그램에서 코 루틴을 사용하는 동안 좋아 나 자신에 의해 답을 발견했다. 알림, 나는 차이를 찾고 있었다 사용 . 나는 순차적으로 비동기 코드를 실행할 수 있었다 Executor
나는 코 루틴으로 전환에서 큰 혜택은 무엇입니까 그래서, 코 루틴의 가장 큰 장점이라고 어디서나 보았다?
먼저, 당신은이 것을 내 마지막 샘플에서 볼 수있는 xxxViewModel
비동기 작업을 스레드 무엇을 선택한다면이 실행되었다는 것을. 이것은 내 의견으로는 설계 결함입니다. 뷰 모델은 알고 더 적은 스레드를 선택하는 Responsibility는 없어야합니다.
이제 코 루틴으로, I는 다음과 같이 쓸 수 있습니다 :
// ViewModel
viewModelScope.launch {
repository.insert(Title(title = "Hola", id = 1))
myLiveData.value = "coroutines are great"
}
// Repository
suspend fun insert(title: Title)
{
withContext(Dispatchers.IO)
{
dao.insertTitle(title)
}
}
우리는이가 선택한 어떤 Dispatcher가 뷰 모델을 작업을 관리하고 있지 않은지 기능을 중단 것을 볼 수 있습니다. 이 저장소에이 논리를 캡슐화 나는이 훨씬 좋네요을 찾을 수 있습니다.
또한, 코 루틴의 취소는보다 훨씬 쉽게 ExecutorService
취소. ExecutorService
정말 취소을 위해 만든되지 않습니다. 그것은이 shutdown()
방법을하지만, 그것은 모든 작업이 취소됩니다 ExecutorService
, 우리는 취소해야 할뿐만 아니라 하나. 우리의 범위는 경우 ExecutorService
우리의 ViewModel의보다 큰, 우리는 끝장. 코 루틴, 그것은 너무 쉽게 당신이 그것에 대해 걱정하지 않아도됩니다. 당신이 사용하는 경우 viewModelScope
(당신은한다), 그것은 뷰 모델의이 범위 내의 모든 코 루틴을 취소합니다 onCleared()
자체에 의해, 방법.
결론적으로, 코 루틴은 안드로이드에 비해 구성 요소가 훨씬 더 통합이 ExecutorService
더 나은, 그리고 청소기 관리 기능을, 그리고 예 그들은 경량입니다. 나는 그것이 안드로이드 킬러 인수 생각하지 않는다하더라도, 그것은 더 가벼운 구성 요소가 여전히 좋다.