Android中各種Time API詳細(xì)
1、時(shí)間API
為了跟蹤性能,我們需要測量時(shí)間間隔,即兩個(gè)時(shí)間點(diǎn)之間的差異。 JDK 為我們提供了兩種獲取當(dāng)前時(shí)間的方法:
// Milliseconds since Unix epoch (00:00:00 UTC on 1 January 1970) System.currentTimeMillis() // Nanoseconds since the VM started. System.nanoTime()
Android 提供了一個(gè) SystemClock 類,它增加了一些:
// (API 29) Clock that starts at Unix epoch. // Synchronized using the device's location provider. SystemClock.currentGnssTimeClock() // Milliseconds running in the current thread. SystemClock.currentThreadTimeMillis() // Milliseconds since boot, including time spent in sleep. SystemClock.elapsedRealtime() // Nanoseconds since boot, including time spent in sleep. SystemClock.elapsedRealtimeNanos() // Milliseconds since boot, not counting time spent in deep sleep. SystemClock.uptimeMillis()
我們應(yīng)該選擇哪一個(gè)? SystemClock 的 javadoc 有助于回答這個(gè)問題:
System#currentTimeMillis 可以由用戶或電話網(wǎng)絡(luò)設(shè)置,因此時(shí)間可能會不可預(yù)測地向后或向前跳躍。 間隔或經(jīng)過時(shí)間測量應(yīng)使用不同的時(shí)鐘。
SystemClock#uptimeMillis 在系統(tǒng)進(jìn)入深度睡眠時(shí)停止。 這是大多數(shù)間隔計(jì)時(shí)的基礎(chǔ),例如 Thread#sleep(long) 、Object#wait(long) 和 System#nanoTime。 當(dāng)間隔不跨越設(shè)備休眠時(shí),該時(shí)鐘適用于間隔計(jì)時(shí)。
SystemClock#elapsedRealtime 和 SystemClock#elapsedRealtimeNanos 包括深度睡眠。 該時(shí)鐘是通用間隔計(jì)時(shí)的推薦基礎(chǔ)。
應(yīng)用程序的性能對深度睡眠中發(fā)生的事情沒有影響,所以我們最好的選擇是 SystemClock.uptimeMillis() 和 System.nanoTime()
2、uptimeMillis() vs nanoTime()
System.nanoTime() 比 uptimeMillis() 更精確,但這僅對微基準(zhǔn)測試有用。 在生產(chǎn)中跟蹤性能時(shí),我們需要毫秒級的分辨率。
讓我們比較一下它們的性能影響。 我克隆了 Android Benchmark Samples 存儲庫并添加了以下測試:
@LargeTest
@RunWith(AndroidJUnit4::class)
class TimingBenchmark {
@get:Rule
val benchmarkRule = BenchmarkRule()
@Test
fun nanoTime() {
benchmarkRule.measureRepeated {
System.nanoTime()
}
}
@Test
fun uptimeMillis() {
benchmarkRule.measureRepeated {
SystemClock.uptimeMillis()
}
}
}
在運(yùn)行 Android 10 的 Pixel 3 上的結(jié)果:
System.nanoTime() 中值時(shí)間:208 ns
SystemClock.uptimeMillis() 中值時(shí)間:116 ns
SystemClock.uptimeMillis() 幾乎快兩倍! 雖然這種差異應(yīng)該不會對應(yīng)用程序產(chǎn)生任何有意義的影響,但我們能弄清楚為什么它要快得多嗎?
3、uptimeMillis() 實(shí)現(xiàn)
SystemClock.uptimeMillis() 實(shí)現(xiàn)為帶有@CriticalNative 注釋的本機(jī)方法。 CriticalNative 為不包含對象的方法提供更快的 JNI 轉(zhuǎn)換。
public final class SystemClock {
@CriticalNative
native public static long uptimeMillis();
}
原生實(shí)現(xiàn)在 SystemClock.c++ 中:
int64_t uptimeMillis()
{
int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
return (int64_t) nanoseconds_to_milliseconds(when);
}
systemTime() 在 Timers.cpp 中定義:
nsecs_t systemTime(int clock) {
static constexpr clockid_t clocks[] = {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
CLOCK_PROCESS_CPUTIME_ID,
CLOCK_THREAD_CPUTIME_ID,
CLOCK_BOOTTIME
};
timespec t = {};
clock_gettime(clocks[clock], &t);
return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}
4、nanoTime() 實(shí)現(xiàn)
System.nanoTime() 也被實(shí)現(xiàn)為帶有@CriticalNative 注釋的本地方法。
public final class System {
@CriticalNative
public static native long nanoTime();
}
本地實(shí)現(xiàn)在 System.c 中:
static jlong System_nanoTime() {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now.tv_sec * 1000000000LL + now.tv_nsec;
}
這兩個(gè)實(shí)現(xiàn)其實(shí)很相似,都調(diào)用clock_gettime() 。
事實(shí)證明,@CriticalNative 最近才被添加到 System.nanoTime() ,這就解釋了為什么它變慢了!
結(jié)論:
在生產(chǎn)應(yīng)用中跟蹤性能時(shí):
對于大多數(shù)用例,毫秒分辨率就足夠了。 要測量時(shí)間間隔,請使用 SystemClock.uptimeMillis() 或 System.nanoTime() 。 后者在較舊的 Android 版本上速度較慢,但這在這里無關(guān)緊要。
到此這篇關(guān)于Android中各種Time API詳細(xì)的文章就介紹到這了,更多相關(guān)Android中各種Time API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flutter源碼分析之自定義控件(RenderBox)指南
寫了兩天的flutter,發(fā)現(xiàn)控件樣式很多,flutter資源很少,本文在于實(shí)用性,可以減少頁面代碼,下面這篇文章主要介紹了Flutter源碼分析之自定義控件(RenderBox)的相關(guān)資料,需要的朋友可以參考下2021-08-08
全面解析Android中對EditText輸入實(shí)現(xiàn)監(jiān)聽的方法
這篇文章主要介紹了Android中對EditText輸入實(shí)現(xiàn)監(jiān)聽的方法,包括一個(gè)仿iOS的帶清除功能的ClearEditText輸入框控件的詳細(xì)使用介紹,需要的朋友可以參考下2016-04-04
Android的WebView與H5前端JS代碼交互的實(shí)例代碼
本篇文章主要介紹了Android的WebView與H5前端JS代碼交互的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-07-07
Android實(shí)現(xiàn)將應(yīng)用崩潰信息發(fā)送給開發(fā)者并重啟應(yīng)用的方法
這篇文章主要介紹了Android實(shí)現(xiàn)將應(yīng)用崩潰信息發(fā)送給開發(fā)者并重啟應(yīng)用的方法,涉及Android錯(cuò)誤處理與應(yīng)用操作的相關(guān)技巧,需要的朋友可以參考下2016-03-03
Android利用RecyclerView實(shí)現(xiàn)列表倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Android利用RecyclerView實(shí)現(xiàn)列表倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
基于Android中獲取資源的id和url方法總結(jié)
下面小編就為大家分享一篇基于Android中獲取資源的id和url方法總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02
Android Framework Application Framework層簡單介紹
這篇文章主要介紹了 Android Framework Application Framework層簡單介紹的相關(guān)資料,需要的朋友可以參考下2016-11-11
Android提高之BLE開發(fā)Android手機(jī)搜索iBeacon基站
這篇文章主要介紹了BLE開發(fā)Android手機(jī)搜索iBeacon基站,需要的朋友可以參考下2014-08-08

