前言
刚刚从事Android开发的人员,大多数情况会遇到线程切换错误,误把子线程也可以当做主线程使用,刷新数据。
看过Looper ,Handler源码的小伙伴想必都知道,如果在子线程刷新数据不过任何操作的前提下,会出现异常情况。
源码就不和大家讲解了。今天和小伙伴们利用设计模式封装一个线程切换工具类。
- 利用单列模式创建对象
private static class ThreadHelperHolder {
private static ThreadHelper instance = new ThreadHelper();
}
private ThreadHelper() {
mMainHandler = new Handler(Looper.getMainLooper());
//创建线程
ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "ThreadHelper #".concat(String.valueOf(mCount.getAndIncrement())));
}
};
//获取CPU数量
int cpuCount = Runtime.getRuntime().availableProcessors();
//核心线程数
int corePoolSize = cpuCount + 1;
//最大线程数
int maxPoolSize = cpuCount * 2 + 1;
//线程池
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(128);
mExecutorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 10, TimeUnit.SECONDS, queue, threadFactory);
}
外部调用方法
public static ThreadHelper getInstance() {
return ThreadHelperHolder.instance;
}
- 利用HandlerThread 来执行耗时操作并利用单列同步锁保证并发性
private synchronized void ensureSubHandler() {
if (mWorkHandler == null) {
HandlerThread handlerThread = new HandlerThread("WorkHandler");
handlerThread.start();
mWorkHandler = new Handler(handlerThread.getLooper());
}
}
- 切换线程
/**
* 异步任务,使用 HandlerThread
*
* @param r
* @return
*/
public boolean runOnHandlerThread(Runnable r) {
ensureSubHandler();
return mWorkHandler.post(r);
}
/**
* 异步延时任务,使用 HandlerThread
*
* @param r
* @param delayMillis
* @return
*/
public boolean postDelayed(Runnable r, long delayMillis) {
ensureSubHandler();
return mWorkHandler.postDelayed(r, delayMillis);
}
/**
* 异步定时任务,使用 HandlerThread
*
* @param r
* @param uptimeMillis
* @return
*/
public boolean postAtTime(Runnable r, long uptimeMillis) {
ensureSubHandler();
return mWorkHandler.postAtTime(r, uptimeMillis);
}
/**
* 主线程任务
*
* @param r
*/
public void runOnUiThread(Runnable r) {
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
r.run();
} else {
mMainHandler.post(r);
}
}
/**
* 主线程延时任务
*
* @param r
* @param delay
* @return
*/
public boolean runOnUiPostDelayed(Runnable r, long delay) {
return mMainHandler.postDelayed(r, delay);
}
/**
* 主线程定时任务
*
* @param r
* @param uptimeMillis
* @return
*/
public boolean runOnUiPostAtTime(Runnable r, long uptimeMillis) {
return mMainHandler.postAtTime(r, uptimeMillis);
}
- 执行操作
/**
* 无返回值的异步任务,使用线程池
*
* @param r
*/
public void execute(Runnable r) {
try {
mExecutorService.execute(r);
} catch (Throwable e) {
Log.e(TAG, e.getMessage());
}
}
/**
* 有返回值的异步任务,使用线程池
*
* @param task
* @param <T>
* @return
*/
public <T> Future<T> submit(Callable<T> task) {
try {
return mExecutorService.submit(task);
} catch (Throwable e) {
Log.e(TAG, e.getMessage());
}
return null;
}
- 移出消息
/**
* 移除主线程的任务
*
* @param r
*/
public void removeUiCallbacks(Runnable r) {
mMainHandler.removeCallbacks(r);
}
/**
* 移除异步线程的任务
*
* @param r
*/
public void removeCallbacks(Runnable r) {
if (mWorkHandler != null) {
mWorkHandler.removeCallbacks(r);
}
}
- 结束线程池
/**
* 结束线程池
*/
public void shutdown() {
if (!mExecutorService.isShutdown()) {
mExecutorService.shutdown();
}
if (mWorkHandler != null) {
mWorkHandler.getLooper().quitSafely();
mWorkHandler.getLooper().getThread().interrupt();
}
}
- 还有一些全局变量
private static final String TAG = "ThreadHelper";
private Handler mMainHandler;
private ExecutorService mExecutorService;
private Handler mWorkHandler;
希望各位小伙伴观看完之后可以点赞收藏,关注一下