/*
* Copyright (c) 2015, 张涛.
* Copyright (c) 2016, CaMnter.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.camnter.newlife.utils;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
/**
* Description:ThreadSwitcher
* Modified from:https://github.com/kymjs/Common/blob/master/Common/common/src/main/java/com/kymjs/common/function/ThreadSwitch.java
* Created by:CaMnter
*/
public final class ThreadSwitcher extends Thread {
private static final int MAX_SIZE = 16;
private static final int GLOBAL_MAX_SIZE = 206;
private volatile boolean isBreak = false;
private final BlockingQueue<Runnable> runnableQueue;
private static final Handler MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper());
private static class GlobalThreadSwitcher {
private static final ThreadSwitcher GLOBAL_THREAD_SWITCHER = new ThreadSwitcher(
GLOBAL_MAX_SIZE);
}
private ThreadSwitcher() {
this(MAX_SIZE);
}
private ThreadSwitcher(int maxSize) {
this.start();
// >= 5.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
this.runnableQueue = new LinkedTransferQueue<>();
} else {
this.runnableQueue = new LinkedBlockingQueue<>(maxSize);
}
}
public static ThreadSwitcher getGlobalThreadSwitcher() {
return GlobalThreadSwitcher.GLOBAL_THREAD_SWITCHER;
}
public static ThreadSwitcher newInstance() {
return new ThreadSwitcher();
}
public static ThreadSwitcher newInstance(final int maxSize) {
return new ThreadSwitcher(maxSize <= 0 ? MAX_SIZE : maxSize);
}
public ThreadSwitcher io(final IO io) {
this.runnableQueue.add(io);
return this;
}
public ThreadSwitcher ui(final UI ui) {
this.runnableQueue.add(ui);
return this;
}
public ThreadSwitcher breakTask() {
this.isBreak = true;
return this;
}
@Override public void run() {
super.run();
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
try {
if (isBreak) {
isBreak = false;
runnableQueue.clear();
if (this != GlobalThreadSwitcher.GLOBAL_THREAD_SWITCHER) {
return;
}
}
final Runnable task = runnableQueue.take();
if (task != null) {
if (task instanceof IO) {
task.run();
} else if (task instanceof UI) {
MAIN_THREAD_HANDLER.post(task);
}
}
} catch (InterruptedException e) {
return;
}
}
}
/**
* UI task abstract interface
*/
public interface UI extends Runnable {}
/**
* IO task abstract interface
*/
public interface IO extends Runnable {}
/**
* Terminate the task abstract interface
*/
public interface Break extends Runnable {}
}