Android中優雅的線程切換寫法(一),接上回繼續寫。在實現延遲執行任務之後,再實現移除延遲任務。這個就需要先做一個棧,把所有的延遲任務put到這個棧中,並以一個唯一tag作爲標記。等到需要移除的時候,通過移除這個tag標記的Runnable就行了。
以上是實現的基本思路,那麼具體做法如下:
1、首先對原有的ThreadUtil類進行修改,增加一個Map集合作爲“任務棧”保存所有的延遲任務。
2、其次修改原來的handler對象實現方式,增加 DO_DELAYED_MAIN_THREAD、DO_DELAYED_CHILD_THREAD 兩個case。用來執行具體的Runnable任務。執行完之後,將Runnable從Map中移除。
3、修改原有的runOnMainThreadDelayed、runOnChildThreadDelayed方法的返回值,讓他們返回唯一的tag標識,這個標識將會用來移除延遲任務。
4、增加一個removeDelayedThread方法,用來根據唯一tag標識來移除延遲任務。
private static final int DO_DELAYED_MAIN_THREAD = 2;
private static final int DO_DELAYED_CHILD_THREAD = 3;
//用於保存所有的延遲執行任務
private static Map<String,Runnable> delayMap = new HashMap<>();
@SuppressLint("HandlerLeak")
private static Handler handler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case DelayedRunChildThread:
runOnChildThread((Runnable) msg.obj);
break;
case DO_DELAYED_MAIN_THREAD:
Runnable main = delayMap.get(msg.obj.toString());
if (main != null){
main.run();
//移除掉被執行的任務
delayMap.remove(msg.obj.toString());
}
break;
case DO_DELAYED_CHILD_THREAD:
Runnable child = delayMap.get(msg.obj.toString());
if (child != null){
runOnChildThread(child);
//移除掉被執行的任務
delayMap.remove(msg.obj.toString());
}
break;
}
}
};
/**
* 在主線程中延遲執行一個Runnable接口
* @param time 延遲時間,以毫秒爲單位
* @return 每個延遲任務的唯一tag標記
*/
public static String runOnMainThreadDelayed(Runnable runnable, long time) {
if (runnable == null || time < 0) return "";
//生成唯一的tag標識
String tag = String.valueOf(runnable.hashCode() + System.currentTimeMillis());
//將Runnable放到待執行的棧中
delayMap.put(tag, runnable);
Message message = Message.obtain();
message.what = DO_DELAYED_MAIN_THREAD;
message.obj = tag;
handler.sendMessageDelayed(message, time);
return tag;
}
/**
* 延遲執行一個子線程
* @param time 延遲時間,以毫秒爲單位
* @param return 每個延遲任務的唯一tag標記
*/
public static String runOnChildThreadDelayed(Runnable runnable, long time) {
if (runnable == null || time < 0) return "";
//生成唯一的tag標識
String tag = String.valueOf(runnable.hashCode() + System.currentTimeMillis());
delayMap.put(tag, runnable);
Message message = Message.obtain();
message.what = DO_DELAYED_CHILD_THREAD;
message.obj = tag;
handler.sendMessageDelayed(message, time);
return tag;
}
/**
* 移除掉還沒有執行的延遲任務
* @param tag 每個延遲任務的唯一標識
*/
public static void removeDelayedThread(String tag){
delayMap.remove(tag);
}