* Use cached resources for widgets
This commit is contained in:
@@ -34,6 +34,7 @@ import android.content.pm.ProviderInfo;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.pm.PackageParser.Component;
|
import android.content.pm.PackageParser.Component;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.CompatibilityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
@@ -166,43 +167,52 @@ public final class ActivityThread {
|
|||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resources getTopLevelResources(String appDir, PackageInfo pkgInfo) {
|
/**
|
||||||
|
* Creates the top level Resources for applications with the given compatibility info.
|
||||||
|
*
|
||||||
|
* @param resDir the resource directory.
|
||||||
|
* @param compInfo the compability info. It will use the default compatibility info when it's
|
||||||
|
* null.
|
||||||
|
*/
|
||||||
|
Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
//Log.w(TAG, "getTopLevelResources: " + appDir);
|
// Resources is app scale dependent.
|
||||||
WeakReference<Resources> wr = mActiveResources.get(appDir);
|
ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
|
||||||
|
//Log.w(TAG, "getTopLevelResources: " + resDir);
|
||||||
|
WeakReference<Resources> wr = mActiveResources.get(key);
|
||||||
Resources r = wr != null ? wr.get() : null;
|
Resources r = wr != null ? wr.get() : null;
|
||||||
if (r != null && r.getAssets().isUpToDate()) {
|
if (r != null && r.getAssets().isUpToDate()) {
|
||||||
//Log.w(TAG, "Returning cached resources " + r + " " + appDir);
|
//Log.w(TAG, "Returning cached resources " + r + " " + resDir);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (r != null) {
|
//if (r != null) {
|
||||||
// Log.w(TAG, "Throwing away out-of-date resources!!!! "
|
// Log.w(TAG, "Throwing away out-of-date resources!!!! "
|
||||||
// + r + " " + appDir);
|
// + r + " " + resDir);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
AssetManager assets = new AssetManager();
|
AssetManager assets = new AssetManager();
|
||||||
if (assets.addAssetPath(appDir) == 0) {
|
if (assets.addAssetPath(resDir) == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ApplicationInfo appInfo;
|
|
||||||
try {
|
//Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
|
||||||
appInfo = getPackageManager().getApplicationInfo(
|
|
||||||
pkgInfo.getPackageName(),
|
|
||||||
PackageManager.GET_SUPPORTS_DENSITIES);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
//Log.i(TAG, "Resource:" + appDir + ", display metrics=" + metrics);
|
|
||||||
DisplayMetrics metrics = getDisplayMetricsLocked(false);
|
DisplayMetrics metrics = getDisplayMetricsLocked(false);
|
||||||
r = new Resources(assets, metrics, getConfiguration(), appInfo);
|
r = new Resources(assets, metrics, getConfiguration(), compInfo);
|
||||||
//Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());
|
//Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());
|
||||||
// XXX need to remove entries when weak references go away
|
// XXX need to remove entries when weak references go away
|
||||||
mActiveResources.put(appDir, new WeakReference<Resources>(r));
|
mActiveResources.put(key, new WeakReference<Resources>(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the top level resources for the given package.
|
||||||
|
*/
|
||||||
|
Resources getTopLevelResources(String resDir, PackageInfo pkgInfo) {
|
||||||
|
return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
|
||||||
|
}
|
||||||
|
|
||||||
final Handler getHandler() {
|
final Handler getHandler() {
|
||||||
return mH;
|
return mH;
|
||||||
}
|
}
|
||||||
@@ -223,6 +233,7 @@ public final class ActivityThread {
|
|||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
private ClassLoader mClassLoader;
|
private ClassLoader mClassLoader;
|
||||||
private Application mApplication;
|
private Application mApplication;
|
||||||
|
private CompatibilityInfo mCompatibilityInfo;
|
||||||
|
|
||||||
private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
|
private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
|
||||||
= new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>();
|
= new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>();
|
||||||
@@ -250,6 +261,7 @@ public final class ActivityThread {
|
|||||||
mBaseClassLoader = baseLoader;
|
mBaseClassLoader = baseLoader;
|
||||||
mSecurityViolation = securityViolation;
|
mSecurityViolation = securityViolation;
|
||||||
mIncludeCode = includeCode;
|
mIncludeCode = includeCode;
|
||||||
|
mCompatibilityInfo = new CompatibilityInfo(aInfo);
|
||||||
|
|
||||||
if (mAppDir == null) {
|
if (mAppDir == null) {
|
||||||
if (mSystemContext == null) {
|
if (mSystemContext == null) {
|
||||||
@@ -283,6 +295,7 @@ public final class ActivityThread {
|
|||||||
mIncludeCode = true;
|
mIncludeCode = true;
|
||||||
mClassLoader = systemContext.getClassLoader();
|
mClassLoader = systemContext.getClassLoader();
|
||||||
mResources = systemContext.getResources();
|
mResources = systemContext.getResources();
|
||||||
|
mCompatibilityInfo = new CompatibilityInfo(mApplicationInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPackageName() {
|
public String getPackageName() {
|
||||||
@@ -1894,6 +1907,32 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static class ResourcesKey {
|
||||||
|
final private String mResDir;
|
||||||
|
final private float mScale;
|
||||||
|
final private int mHash;
|
||||||
|
|
||||||
|
ResourcesKey(String resDir, float scale) {
|
||||||
|
mResDir = resDir;
|
||||||
|
mScale = scale;
|
||||||
|
mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof ResourcesKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ResourcesKey peer = (ResourcesKey) obj;
|
||||||
|
return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static IPackageManager sPackageManager;
|
static IPackageManager sPackageManager;
|
||||||
|
|
||||||
final ApplicationThread mAppThread = new ApplicationThread();
|
final ApplicationThread mAppThread = new ApplicationThread();
|
||||||
@@ -1939,8 +1978,8 @@ public final class ActivityThread {
|
|||||||
= new HashMap<String, WeakReference<PackageInfo>>();
|
= new HashMap<String, WeakReference<PackageInfo>>();
|
||||||
Display mDisplay = null;
|
Display mDisplay = null;
|
||||||
DisplayMetrics mDisplayMetrics = null;
|
DisplayMetrics mDisplayMetrics = null;
|
||||||
HashMap<String, WeakReference<Resources> > mActiveResources
|
HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
|
||||||
= new HashMap<String, WeakReference<Resources> >();
|
= new HashMap<ResourcesKey, WeakReference<Resources> >();
|
||||||
|
|
||||||
// The lock of mProviderMap protects the following variables.
|
// The lock of mProviderMap protects the following variables.
|
||||||
final HashMap<String, ProviderRecord> mProviderMap
|
final HashMap<String, ProviderRecord> mProviderMap
|
||||||
|
|||||||
@@ -1341,21 +1341,8 @@ class ApplicationContext extends Context {
|
|||||||
if (pi != null) {
|
if (pi != null) {
|
||||||
ApplicationContext c = new ApplicationContext();
|
ApplicationContext c = new ApplicationContext();
|
||||||
c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
|
c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
|
||||||
c.init(pi, null, mMainThread);
|
c.init(pi, null, mMainThread, mResources);
|
||||||
if (c.mResources != null) {
|
if (c.mResources != null) {
|
||||||
Resources newRes = c.mResources;
|
|
||||||
if (mResources.getCompatibilityInfo().applicationScale !=
|
|
||||||
newRes.getCompatibilityInfo().applicationScale) {
|
|
||||||
DisplayMetrics dm = mMainThread.getDisplayMetricsLocked(false);
|
|
||||||
c.mResources = new Resources(newRes.getAssets(), dm,
|
|
||||||
newRes.getConfiguration(),
|
|
||||||
mResources.getCompatibilityInfo().copy());
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "loaded context has different scaling. Using container's" +
|
|
||||||
" compatiblity info:" + mResources.getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1417,8 +1404,24 @@ class ApplicationContext extends Context {
|
|||||||
|
|
||||||
final void init(ActivityThread.PackageInfo packageInfo,
|
final void init(ActivityThread.PackageInfo packageInfo,
|
||||||
IBinder activityToken, ActivityThread mainThread) {
|
IBinder activityToken, ActivityThread mainThread) {
|
||||||
|
init(packageInfo, activityToken, mainThread, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final void init(ActivityThread.PackageInfo packageInfo,
|
||||||
|
IBinder activityToken, ActivityThread mainThread,
|
||||||
|
Resources container) {
|
||||||
mPackageInfo = packageInfo;
|
mPackageInfo = packageInfo;
|
||||||
mResources = mPackageInfo.getResources(mainThread);
|
mResources = mPackageInfo.getResources(mainThread);
|
||||||
|
|
||||||
|
if (container != null && container.getCompatibilityInfo().applicationScale !=
|
||||||
|
mResources.getCompatibilityInfo().applicationScale) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "loaded context has different scaling. Using container's" +
|
||||||
|
" compatiblity info:" + container.getDisplayMetrics());
|
||||||
|
}
|
||||||
|
mResources = mainThread.getTopLevelResources(
|
||||||
|
mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
|
||||||
|
}
|
||||||
mMainThread = mainThread;
|
mMainThread = mainThread;
|
||||||
mContentResolver = new ApplicationContentResolver(this, mainThread);
|
mContentResolver = new ApplicationContentResolver(this, mainThread);
|
||||||
|
|
||||||
|
|||||||
@@ -979,12 +979,12 @@ public class PackageParser {
|
|||||||
/**
|
/**
|
||||||
* TODO: enable this before code freeze. b/1967935
|
* TODO: enable this before code freeze. b/1967935
|
||||||
* *
|
* *
|
||||||
|
*/
|
||||||
if ((densities == null || densities.length == 0)
|
if ((densities == null || densities.length == 0)
|
||||||
&& (pkg.applicationInfo.targetSdkVersion
|
&& (pkg.applicationInfo.targetSdkVersion
|
||||||
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
|
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
|
||||||
pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
|
pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,53 +129,30 @@ public class Resources {
|
|||||||
*/
|
*/
|
||||||
public Resources(AssetManager assets, DisplayMetrics metrics,
|
public Resources(AssetManager assets, DisplayMetrics metrics,
|
||||||
Configuration config) {
|
Configuration config) {
|
||||||
this(assets, metrics, config, (ApplicationInfo) null);
|
this(assets, metrics, config, (CompatibilityInfo) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Resources object with ApplicationInfo.
|
* Creates a new Resources object with CompatibilityInfo.
|
||||||
*
|
*
|
||||||
* @param assets Previously created AssetManager.
|
* @param assets Previously created AssetManager.
|
||||||
* @param metrics Current display metrics to consider when
|
* @param metrics Current display metrics to consider when
|
||||||
* selecting/computing resource values.
|
* selecting/computing resource values.
|
||||||
* @param config Desired device configuration to consider when
|
* @param config Desired device configuration to consider when
|
||||||
* selecting/computing resource values (optional).
|
* selecting/computing resource values (optional).
|
||||||
* @param appInfo this resource's application info.
|
* @param compInfo this resource's compatibility info. It will use the default compatibility
|
||||||
|
* info when it's null.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public Resources(AssetManager assets, DisplayMetrics metrics,
|
public Resources(AssetManager assets, DisplayMetrics metrics,
|
||||||
Configuration config, ApplicationInfo appInfo) {
|
Configuration config, CompatibilityInfo compInfo) {
|
||||||
mAssets = assets;
|
mAssets = assets;
|
||||||
mConfiguration.setToDefaults();
|
|
||||||
mMetrics.setToDefaults();
|
mMetrics.setToDefaults();
|
||||||
if (appInfo != null) {
|
if (compInfo == null) {
|
||||||
mCompatibilityInfo = new CompatibilityInfo(appInfo);
|
|
||||||
if (DEBUG_CONFIG) {
|
|
||||||
Log.d(TAG, "compatibility for " + appInfo.packageName + " : " + mCompatibilityInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
|
mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
|
||||||
}
|
|
||||||
updateConfiguration(config, metrics);
|
|
||||||
assets.ensureStringBlocks();
|
|
||||||
if (mCompatibilityInfo.isScalingRequired()) {
|
|
||||||
mPreloadedDrawables = emptySparseArray();
|
|
||||||
} else {
|
} else {
|
||||||
mPreloadedDrawables = sPreloadedDrawables;
|
mCompatibilityInfo = compInfo;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new resources that uses the given compatibility info. Used to create
|
|
||||||
* a context for widgets using the container's compatibility info.
|
|
||||||
* {@see ApplicationContext#createPackageCotnext}.
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public Resources(AssetManager assets, DisplayMetrics metrics,
|
|
||||||
Configuration config, CompatibilityInfo info) {
|
|
||||||
mAssets = assets;
|
|
||||||
mMetrics.setToDefaults();
|
|
||||||
mCompatibilityInfo = info;
|
|
||||||
updateConfiguration(config, metrics);
|
updateConfiguration(config, metrics);
|
||||||
assets.ensureStringBlocks();
|
assets.ensureStringBlocks();
|
||||||
if (mCompatibilityInfo.isScalingRequired()) {
|
if (mCompatibilityInfo.isScalingRequired()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user