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);
        }
    }