Created
May 30, 2023 02:43
-
-
Save zty5678/91296c576579e5694d1d93be2aac30f4 to your computer and use it in GitHub Desktop.
UIJobScheduler: 记录当前一帧进行的操作所花费的时间,如果不够进行下一个操作,则将下一个操作放到下一帧,以此来增加画面的流畅度。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.os.Handler; | |
import android.view.Choreographer; | |
import java.util.ArrayDeque; | |
import java.util.concurrent.Callable; | |
public class UIJobScheduler { | |
private final static float MAX_JOB_TIMES_MS = 4f; | |
private static long elapsed = 0L; | |
private static ArrayDeque<Callable> jobQueue = new ArrayDeque<>(); | |
private static Handler handler = new Handler(); | |
private static boolean isOverMaxtime() { | |
return elapsed > MAX_JOB_TIMES_MS * 1_000_000; | |
} | |
public static void submitJob(final Callable job) { | |
jobQueue.add(job); | |
if (jobQueue.size() == 1) { | |
handler.post(new Runnable() { | |
@Override | |
public void run() { | |
processJobs(); | |
} | |
}); | |
} | |
} | |
private static void processJobs() { | |
while (!jobQueue.isEmpty() && !isOverMaxtime()) { | |
long start = System.nanoTime(); | |
Callable currentJob = jobQueue.poll(); | |
if (currentJob != null) { | |
try { | |
currentJob.call(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
elapsed += System.nanoTime() - start; | |
} | |
if (jobQueue.isEmpty()) { | |
elapsed = 0; | |
} else { | |
onNextFrame(new Choreographer.FrameCallback() { | |
@Override | |
public void doFrame(long frameTimeNanos) { | |
elapsed = 0; | |
processJobs(); | |
} | |
}); | |
} | |
} | |
private static void onNextFrame(Choreographer.FrameCallback callback) { | |
Choreographer.getInstance().postFrameCallback(callback); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object UIJobScheduler { | |
private const val MAX_JOB_TIME_MS: Float = 4f | |
private var elapsed = 0L | |
private val jobQueue = ArrayDeque<() -> Unit>() | |
private val isOverMaxTime get() = elapsed > MAX_JOB_TIME_MS * 1_000_000 | |
private val handler = Handler() | |
fun submitJob(job: () -> Unit) { | |
jobQueue.add(job) | |
if (jobQueue.size == 1) { | |
handler.post { processJobs() } | |
} | |
} | |
private fun processJobs() { | |
while (!jobQueue.isEmpty() && !isOverMaxTime) { | |
val start = System.nanoTime() | |
jobQueue.poll().invoke() | |
elapsed += System.nanoTime() - start | |
} | |
if (jobQueue.isEmpty()) { | |
elapsed = 0 | |
} else if (isOverMaxTime) { | |
onNextFrame { | |
elapsed = 0 | |
processJobs() | |
} | |
} | |
} | |
private fun onNextFrame(callback: () -> Unit) = | |
Choreographer.getInstance().postFrameCallback { callback() } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment