kotlin协程切换线程在编码过程中非常简单高效,在Java中简单模拟一下
首先定义一个注解,用来作为线程切换的标记
@Retention(RetentionPolicy.SOURCE)
@IntDef({Dispatcher.IO, Dispatcher.Main})
public @interface Dispatcher {
int IO = 0;
int Main = 1;
}
接着构建一个"协程"类:其中主要由线程池以及Handler构成
public class Coroutine {
private static final Handler mHandler = new Handler(Looper.getMainLooper());
private static final ThreadPoolExecutor es = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
public static void withContext(@com.enjoy.okhttp.coroutine.Dispatcher int type, Runnable runnable) {
if (runnable == null) {
throw new RuntimeException("no runnable can be executed");
}
if (type == Dispatcher.IO) {
es.execute(runnable);
} else if (type == Dispatcher.Main) {
mHandler.post(runnable);
}
}
}
再看看使用:
//将任务切换到IO线程中执行
withContext(Dispatcher.IO, () -> {
try {
Response response = call.execute();
ResponseBody responseBody = response.body();
//切换到主线程更新UI
withContext(Dispatcher.Main, () -> {
try {
assert responseBody != null;
byte[] bitMapBytes = responseBody.bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bitMapBytes, 0, bitMapBytes.length);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
});
然后看看效果
让我们再来看一下kotlin中的协程写法
//换到子线程执行耗时任务
withContext(Dispatchers.IO) {
val response = call.execute()
val responseBody = response.body()
//主线程更新UI
withContext(Dispatchers.Main) {
val bitMapBytes = responseBody?.bytes()
val bitMap = BitmapFactory.decodeByteArray(bitMapBytes, 0, bitMapBytes?.size!!)
iv_show?.setImageBitmap(bitMap)
}
}
可以看出来,除了kotlin的lambda可以简写以外,其他方面区别不大。
然后简单深入看一下kt 的协程,点开 Dispatchers,
override val executor: Executor
get() = coroutineScheduler、
private fun createScheduler() = CoroutineScheduler(corePoolSize, maxPoolSize, idleWorkerKeepAliveNs, schedulerName)、
internal class CoroutineScheduler(
@JvmField val corePoolSize: Int,
@JvmField val maxPoolSize: Int,
@JvmField val idleWorkerKeepAliveNs: Long = IDLE_WORKER_KEEP_ALIVE_NS,
@JvmField val schedulerName: String = DEFAULT_SCHEDULER_NAME
) : Executor, Closeable {
init {
require(corePoolSize >= MIN_SUPPORTED_POOL_SIZE) {
"Core pool size $corePoolSize should be at least $MIN_SUPPORTED_POOL_SIZE"
}
require(maxPoolSize >= corePoolSize) {
"Max pool size $maxPoolSize should be greater than or equals to core pool size $corePoolSize"
}
require(maxPoolSize <= MAX_SUPPORTED_POOL_SIZE) {
"Max pool size $maxPoolSize should not exceed maximal supported number of threads $MAX_SUPPORTED_POOL_SIZE"
}
require(idleWorkerKeepAliveNs > 0) {
"Idle worker keep alive time $idleWorkerKeepAliveNs must be positive"
}
}
...
有没有很眼熟,对了就是线程池。