5月 192020
本文基于Android8.1系统
应用执行过程:在launcher中打开一个无任何组件的应用
updateConfiguration函数增加计时后的代码(使用SystemClock.elapsedRealtime()来计算时间,单位:毫秒)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
public void updateConfiguration(Configuration config, DisplayMetrics metrics, CompatibilityInfo compat) { new Exception().printStackTrace(); Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesImpl#updateConfiguration"); try { long starttime = SystemClock.elapsedRealtime(); synchronized (mAccessLock) { if (false) { Slog.i(TAG, "**** Updating config of " + this + ": old config is " + mConfiguration + " old compat is " + mDisplayAdjustments.getCompatibilityInfo()); Slog.i(TAG, "**** Updating config of " + this + ": new config is " + config + " new compat is " + compat); } if (compat != null) { mDisplayAdjustments.setCompatibilityInfo(compat); } if (metrics != null) { mMetrics.setTo(metrics); } Slog.d(TAG, "time1 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; // NOTE: We should re-arrange this code to create a Display // with the CompatibilityInfo that is used everywhere we deal // with the display in relation to this app, rather than // doing the conversion here. This impl should be okay because // we make sure to return a compatible display in the places // where there are public APIs to retrieve the display... but // it would be cleaner and more maintainable to just be // consistently dealing with a compatible display everywhere in // the framework. mDisplayAdjustments.getCompatibilityInfo().applyToDisplayMetrics(mMetrics); Slog.d(TAG, "time2 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; final @Config int configChanges = calcConfigChanges(config); Slog.d(TAG, "time3 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; // If even after the update there are no Locales set, grab the default locales. LocaleList locales = mConfiguration.getLocales(); if (locales.isEmpty()) { locales = LocaleList.getDefault(); mConfiguration.setLocales(locales); } Slog.d(TAG, "time4 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) { if (locales.size() > 1) { // The LocaleList has changed. We must query the AssetManager's available // Locales and figure out the best matching Locale in the new LocaleList. String[] availableLocales = mAssets.getNonSystemLocales(); Slog.d(TAG, "time5_1 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if (LocaleList.isPseudoLocalesOnly(availableLocales)) { Slog.d(TAG, "time5_2 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; // No app defined locales, so grab the system locales. availableLocales = mAssets.getLocales(); Slog.d(TAG, "time5_3 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if (LocaleList.isPseudoLocalesOnly(availableLocales)) { availableLocales = null; } Slog.d(TAG, "time5_4 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; } if (availableLocales != null) { final Locale bestLocale = locales.getFirstMatchWithEnglishSupported( availableLocales); Slog.d(TAG, "time5_5 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if (bestLocale != null && bestLocale != locales.get(0)) { mConfiguration.setLocales(new LocaleList(bestLocale, locales)); Slog.d(TAG, "time5_6 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; } } } } Slog.d(TAG, "time5 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) { mMetrics.densityDpi = mConfiguration.densityDpi; mMetrics.density = mConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; } Slog.d(TAG, "time6 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; // Protect against an unset fontScale. mMetrics.scaledDensity = mMetrics.density * (mConfiguration.fontScale != 0 ? mConfiguration.fontScale : 1.0f); final int width, height; if (mMetrics.widthPixels >= mMetrics.heightPixels) { width = mMetrics.widthPixels; height = mMetrics.heightPixels; } else { //noinspection SuspiciousNameCombination width = mMetrics.heightPixels; //noinspection SuspiciousNameCombination height = mMetrics.widthPixels; } final int keyboardHidden; if (mConfiguration.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO && mConfiguration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) { keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT; } else { keyboardHidden = mConfiguration.keyboardHidden; } mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc, adjustLanguageTag(mConfiguration.getLocales().get(0).toLanguageTag()), mConfiguration.orientation, mConfiguration.touchscreen, mConfiguration.densityDpi, mConfiguration.keyboard, keyboardHidden, mConfiguration.navigation, width, height, mConfiguration.smallestScreenWidthDp, mConfiguration.screenWidthDp, mConfiguration.screenHeightDp, mConfiguration.screenLayout, mConfiguration.uiMode, mConfiguration.colorMode, Build.VERSION.RESOURCES_SDK_INT); Slog.d(TAG, "time7 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; if (DEBUG_CONFIG) { Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration + " final compat is " + mDisplayAdjustments.getCompatibilityInfo()); } mDrawableCache.onConfigurationChange(configChanges); Slog.d(TAG, "time8 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; Slog.d(TAG, "time9 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; mColorDrawableCache.onConfigurationChange(configChanges); Slog.d(TAG, "time10 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; mComplexColorCache.onConfigurationChange(configChanges); Slog.d(TAG, "time11 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; mAnimatorCache.onConfigurationChange(configChanges); Slog.d(TAG, "time12 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; mStateListAnimatorCache.onConfigurationChange(configChanges); Slog.d(TAG, "time13 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; flushLayoutCache(); Slog.d(TAG, "time14 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; } synchronized (sSync) { if (mPluralRule != null) { mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().get(0)); } } Slog.d(TAG, "time15 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime();; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } |
会间接调用到LocaleList.java中的computeFirstMatchIndex函数
此函数加时间计数后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
private int computeFirstMatchIndex(Collection<String> supportedLocales, boolean assumeEnglishIsSupported) { if (mList.length == 1) { // just one locale, perhaps the most common scenario return 0; } if (mList.length == 0) { // empty locale list return -1; } long starttime = SystemClock.elapsedRealtime(); int bestIndex = Integer.MAX_VALUE; // Try English first, so we can return early if it's in the LocaleList if (assumeEnglishIsSupported) { final int idx = findFirstMatchIndex(EN_LATN); Slog.d(TAG, "computeFirstMatchIndex1 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime(); if (idx == 0) { // We have a match on the first locale, which is good enough return 0; } else if (idx < bestIndex) { bestIndex = idx; } } for (String languageTag : supportedLocales) { final Locale supportedLocale = Locale.forLanguageTag(languageTag); Slog.d(TAG, "computeFirstMatchIndex2 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime(); // We expect the average length of locale lists used for locale resolution to be // smaller than three, so it's OK to do this as an O(mn) algorithm. final int idx = findFirstMatchIndex(supportedLocale); Slog.d(TAG, "computeFirstMatchIndex3 : " + (SystemClock.elapsedRealtime() - starttime) + ", by liuderu"); starttime = SystemClock.elapsedRealtime(); if (idx == 0) { // We have a match on the first locale, which is good enough return 0; } else if (idx < bestIndex) { bestIndex = idx; } } if (bestIndex == Integer.MAX_VALUE) { // no match was found, so we fall back to the first locale in the locale list return 0; } else { return bestIndex; } } |
执行后的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
05-19 05:20:19.008 3769 3769 D Resources: time1 : 2, by liuderu 05-19 05:20:19.014 3769 3769 D Resources: time2 : 1, by liuderu 05-19 05:20:19.015 3769 3769 D Resources: time3 : 1, by liuderu 05-19 05:20:19.024 3769 3769 D Resources: time4 : 8, by liuderu 05-19 05:20:19.024 3769 3769 D Resources: time5_1 : 0, by liuderu 05-19 05:20:19.027 3769 3769 D Resources: time5_2 : 0, by liuderu 05-19 05:20:19.042 3769 3769 D Resources: time5_3 : 8, by liuderu 05-19 05:20:19.043 3769 3769 D Resources: time5_4 : 1, by liuderu 05-19 05:20:19.211 3769 3769 D LocaleList: computeFirstMatchIndex1 : 167, by liuderu 05-19 05:20:19.229 3769 3769 D LocaleList: computeFirstMatchIndex2 : 15, by liuderu 05-19 05:20:19.235 3769 3769 D LocaleList: computeFirstMatchIndex3 : 5, by liuderu 05-19 05:20:19.253 3769 3769 D LocaleList: computeFirstMatchIndex2 : 18, by liuderu 05-19 05:20:19.265 3769 3769 D LocaleList: computeFirstMatchIndex3 : 10, by liuderu 05-19 05:20:19.271 3769 3769 D LocaleList: computeFirstMatchIndex2 : 6, by liuderu 05-19 05:20:19.378 3769 3769 D LocaleList: computeFirstMatchIndex3 : 98, by liuderu 05-19 05:20:19.397 3769 3769 D LocaleList: computeFirstMatchIndex2 : 11, by liuderu 05-19 05:20:19.433 3769 3769 D LocaleList: computeFirstMatchIndex3 : 36, by liuderu 05-19 05:20:19.435 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.450 3769 3769 D LocaleList: computeFirstMatchIndex3 : 15, by liuderu 05-19 05:20:19.451 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.463 3769 3769 D LocaleList: computeFirstMatchIndex3 : 12, by liuderu 05-19 05:20:19.465 3769 3769 D LocaleList: computeFirstMatchIndex2 : 2, by liuderu 05-19 05:20:19.477 3769 3769 D LocaleList: computeFirstMatchIndex3 : 11, by liuderu 05-19 05:20:19.478 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.478 3769 3769 D LocaleList: computeFirstMatchIndex3 : 0, by liuderu 05-19 05:20:19.480 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.491 3769 3769 D LocaleList: computeFirstMatchIndex3 : 11, by liuderu 05-19 05:20:19.492 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.493 3769 3769 D LocaleList: computeFirstMatchIndex3 : 0, by liuderu 05-19 05:20:19.494 3769 3769 D LocaleList: computeFirstMatchIndex2 : 1, by liuderu 05-19 05:20:19.501 3769 3769 D LocaleList: computeFirstMatchIndex3 : 6, by liuderu 05-19 05:20:19.501 3769 3769 D Resources: time5_5 : 458, by liuderu 05-19 05:20:19.502 3769 3769 D Resources: time5 : 0, by liuderu 05-19 05:20:19.502 3769 3769 D Resources: time6 : 0, by liuderu 05-19 05:20:19.503 3769 3769 D Resources: time7 : 1, by liuderu 05-19 05:20:19.503 3769 3769 D Resources: time8 : 0, by liuderu 05-19 05:20:19.503 3769 3769 D Resources: time9 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time10 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time11 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time12 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time13 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time14 : 0, by liuderu 05-19 05:20:19.504 3769 3769 D Resources: time15 : 0, by liuderu |
由此可见time5_5耗时较长,time5_5的耗时是因为computeFirstMatchIndex中的循环造成的。
而且在一个应用启动过程中要执行两次updateConfiguration,所以这个值得研究一下。
Sorry, the comment form is closed at this time.