下面列出了怎么用android.content.ComponentCallbacks2的API类实例代码及写法,或者点击链接到github查看源代码。
final void handleLowMemory() {
ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
}
final int N = callbacks.size();
for (int i=0; i<N; i++) {
callbacks.get(i).onLowMemory();
}
// Ask SQLite to free up as much memory as it can, mostly from its page caches.
if (Process.myUid() != Process.SYSTEM_UID) {
int sqliteReleased = SQLiteDatabase.releaseMemory();
EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
}
// Ask graphics to free up as much as possible (font/image caches)
Canvas.freeCaches();
// Ask text layout engine to free also as much as possible
Canvas.freeTextLayoutCaches();
BinderInternal.forceGc("mem");
}
final void handleTrimMemory(int level) {
if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
final WindowManagerImpl windowManager = WindowManagerImpl.getDefault();
windowManager.startTrimMemory(level);
ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
}
final int N = callbacks.size();
for (int i = 0; i < N; i++) {
callbacks.get(i).onTrimMemory(level);
}
windowManager.endTrimMemory();
}
final void handleLowMemory() {
ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
}
final int N = callbacks.size();
for (int i=0; i<N; i++) {
callbacks.get(i).onLowMemory();
}
// Ask SQLite to free up as much memory as it can, mostly from its page caches.
if (Process.myUid() != Process.SYSTEM_UID) {
int sqliteReleased = SQLiteDatabase.releaseMemory();
EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
}
// Ask graphics to free up as much as possible (font/image caches)
Canvas.freeCaches();
BinderInternal.forceGc("mem");
}
public void trimMemory(int level) {
if (ThreadedRenderer.isAvailable()) {
if (shouldDestroyEglContext(level)) {
// Destroy all hardware surfaces and resources associated to
// known windows
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).destroyHardwareResources();
}
}
// Force a full memory flush
level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
}
ThreadedRenderer.trimMemory(level);
if (ThreadedRenderer.sTrimForeground) {
doTrimForeground();
}
}
}
private void doTrimForeground() {
boolean hasVisibleWindows = false;
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
final ViewRootImpl root = mRoots.get(i);
if (root.mView != null && root.getHostVisibility() == View.VISIBLE
&& root.mAttachInfo.mThreadedRenderer != null) {
hasVisibleWindows = true;
} else {
root.destroyHardwareResources();
}
}
}
if (!hasVisibleWindows) {
ThreadedRenderer.trimMemory(
ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
}
}
@Override
public void onTrimMemory(int i) {
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
Log.d("topActivity", "CURRENT Activity ::"
+ taskInfo.get(0).topActivity.getClassName());
if (taskInfo != null && taskInfo.size() > 0) {
ComponentName componentInfo = taskInfo.get(0).topActivity;
packageName = componentInfo.getPackageName();
}
if (!packageName.equals(getPackageName()) && i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
// We're in the Background
wentToBg = true;
Log.d(TAG, "wentToBg: " + wentToBg);
}
}
@Test
public void testBackgroundStateChangeCallbacks() {
FirebaseApp firebaseApp = FirebaseApp.initializeApp(targetContext, OPTIONS, "myApp");
firebaseApp.setAutomaticResourceManagementEnabled(true);
final AtomicBoolean backgroundState = new AtomicBoolean();
final AtomicInteger callbackCount = new AtomicInteger();
firebaseApp.addBackgroundStateChangeListener(
background -> {
backgroundState.set(background);
callbackCount.incrementAndGet();
});
assertThat(callbackCount.get()).isEqualTo(0);
// App moves to the background.
backgroundDetector.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
assertThat(callbackCount.get()).isEqualTo(1);
assertThat(backgroundState.get()).isTrue();
// App moves to the foreground.
backgroundDetector.onActivityResumed(null);
assertThat(callbackCount.get()).isEqualTo(2);
assertThat(backgroundState.get()).isFalse();
}
@Test
public void testRemovedBackgroundStateChangeCallbacksDontFire() {
FirebaseApp firebaseApp = FirebaseApp.initializeApp(targetContext, OPTIONS, "myApp");
final AtomicInteger callbackCount = new AtomicInteger();
FirebaseApp.BackgroundStateChangeListener listener =
background -> callbackCount.incrementAndGet();
firebaseApp.addBackgroundStateChangeListener(listener);
firebaseApp.removeBackgroundStateChangeListener(listener);
// App moves to the background.
backgroundDetector.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
// App moves to the foreground.
backgroundDetector.onActivityResumed(null);
assertThat(callbackCount.get()).isEqualTo(0);
}
@Override
public void onTrimMemory(int level) {
// Determine which lifecycle or system event was raised.
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
// Curently ignore these levels. They are handled somewhere else.
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
// It looks like these come in all at the same time so just always suspend inactive Sessions.
Log.d(LOGTAG, "Memory pressure, suspending inactive sessions.");
SessionStore.get().suspendAllInactiveSessions();
break;
default:
Log.e(LOGTAG, "onTrimMemory unknown level: " + level);
break;
}
}
/**
* Used by applications to simulate a memory pressure signal. By throwing certain intent
* actions.
*/
public static boolean handleDebugIntent(Activity activity, String action) {
if (ACTION_LOW_MEMORY.equals(action)) {
simulateLowMemoryPressureSignal(activity);
} else if (ACTION_TRIM_MEMORY.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
} else if (ACTION_TRIM_MEMORY_RUNNING_CRITICAL.equals(action)) {
simulateTrimMemoryPressureSignal(activity,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL);
} else if (ACTION_TRIM_MEMORY_MODERATE.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_MODERATE);
} else {
return false;
}
return true;
}
@Override
public void onTrimMemory(int level) {
ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(this);
if (imageLoader != null) {
Log.i(TAG, "Memory Trim Level: " + level);
if (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
imageLoader.onLowMemory(0.75f);
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
imageLoader.onLowMemory(0.50f);
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE) {
imageLoader.onLowMemory(0.25f);
}
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
imageLoader.onLowMemory(0.25f);
}
}
}
@Override
public void onTrimMemory(int level) {
switch(level) {
// Trims memory when it reaches a moderate level and the session is inactive
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
if(session.isActive()) break;
// Trims memory when it reaches a critical level
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
Log.w(TAG, "Control resources are being removed due to system's low memory (Level: " + level + ")");
destroy();
break;
}
}
@CalledByNative
private static void registerSystemCallback() {
ContextUtils.getApplicationContext().registerComponentCallbacks(
new ComponentCallbacks2() {
@Override
public void onTrimMemory(int level) {
maybeNotifyMemoryPresure(level);
}
@Override
public void onLowMemory() {
nativeOnMemoryPressure(MemoryPressureLevel.CRITICAL);
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
});
}
/**
* Used by applications to simulate a memory pressure signal. By throwing certain intent
* actions.
*/
public static boolean handleDebugIntent(Activity activity, String action) {
if (ACTION_LOW_MEMORY.equals(action)) {
simulateLowMemoryPressureSignal(activity);
} else if (ACTION_TRIM_MEMORY.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
} else if (ACTION_TRIM_MEMORY_RUNNING_CRITICAL.equals(action)) {
simulateTrimMemoryPressureSignal(activity,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL);
} else if (ACTION_TRIM_MEMORY_MODERATE.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_MODERATE);
} else {
return false;
}
return true;
}
/**
* Register ComponentCallbacks2 to receive memory pressure signals.
*
*/
@CalledByNative
private static void registerComponentCallbacks() {
sCallbacks = new ComponentCallbacks2() {
@Override
public void onTrimMemory(int level) {
if (level != ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
nativeOnTrimMemory(level);
}
}
@Override
public void onLowMemory() {
// Don't support old onLowMemory().
}
@Override
public void onConfigurationChanged(Configuration config) {
}
};
ContextUtils.getApplicationContext().registerComponentCallbacks(sCallbacks);
}
@Override
public void onTrimMemory(int level) {
ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(this);
if(imageLoader != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Log.i(TAG, "Memory Trim Level: " + level);
if (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
imageLoader.onLowMemory(0.75f);
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
imageLoader.onLowMemory(0.50f);
} else if(level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE) {
imageLoader.onLowMemory(0.25f);
}
} else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
imageLoader.onLowMemory(0.25f);
} else if(level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
imageLoader.onLowMemory(0.75f);
}
}
}
/**
* @inheritDoc
*/
@Override
public void trimMemory(int level) {
if(level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
emptyCache(); //dump the cache
}
else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE){
trimCache(0.5f); // trim to half the max size
}
else if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND){
trimCache(0.7f); // trim to one seventh max size
}
else if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL){
trimCache(0.2f); // trim to one fifth max size
}
}
/**
* 获取修剪级别的名称
*/
@NonNull
public static String getTrimLevelName(int level) {
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
return "COMPLETE";
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
return "MODERATE";
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
return "BACKGROUND";
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
return "UI_HIDDEN";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
return "RUNNING_CRITICAL";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
return "RUNNING_LOW";
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
return "RUNNING_MODERATE";
default:
return "UNKNOWN";
}
}
@CalledByNative
private static void registerSystemCallback(Context context) {
context.registerComponentCallbacks(
new ComponentCallbacks2() {
@Override
public void onTrimMemory(int level) {
maybeNotifyMemoryPresure(level);
}
@Override
public void onLowMemory() {
nativeOnMemoryPressure(MemoryPressureLevelList.MEMORY_PRESSURE_CRITICAL);
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
});
}
/**
* Used by applications to simulate a memory pressure signal. By throwing certain intent
* actions.
*/
public static boolean handleDebugIntent(Activity activity, String action) {
if (ACTION_LOW_MEMORY.equals(action)) {
simulateLowMemoryPressureSignal(activity);
} else if (ACTION_TRIM_MEMORY.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
} else if (ACTION_TRIM_MEMORY_RUNNING_CRITICAL.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_MODERATE);
} else if (ACTION_TRIM_MEMORY_MODERATE.equals(action)) {
simulateTrimMemoryPressureSignal(activity,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL);
} else {
return false;
}
return true;
}
@CalledByNative
private static void registerSystemCallback(Context context) {
context.registerComponentCallbacks(
new ComponentCallbacks2() {
@Override
public void onTrimMemory(int level) {
maybeNotifyMemoryPresure(level);
}
@Override
public void onLowMemory() {
nativeOnMemoryPressure(MemoryPressureLevelList.MEMORY_PRESSURE_CRITICAL);
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
});
}
/**
* Used by applications to simulate a memory pressure signal. By throwing certain intent
* actions.
*/
public static boolean handleDebugIntent(Activity activity, String action) {
if (ACTION_LOW_MEMORY.equals(action)) {
simulateLowMemoryPressureSignal(activity);
} else if (ACTION_TRIM_MEMORY.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
} else if (ACTION_TRIM_MEMORY_RUNNING_CRITICAL.equals(action)) {
simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_MODERATE);
} else if (ACTION_TRIM_MEMORY_MODERATE.equals(action)) {
simulateTrimMemoryPressureSignal(activity,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL);
} else {
return false;
}
return true;
}
final void handleTrimMemory(int level) {
WindowManagerImpl.getDefault().trimMemory(level);
ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
}
final int N = callbacks.size();
for (int i=0; i<N; i++) {
callbacks.get(i).onTrimMemory(level);
}
}
public static boolean shouldDestroyEglContext(int trimLevel) {
// On low-end gfx devices we trim when memory is moderate;
// on high-end devices we do this when low.
if (trimLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
return true;
}
if (trimLevel >= ComponentCallbacks2.TRIM_MEMORY_MODERATE
&& !ActivityManager.isHighEndGfx()) {
return true;
}
return false;
}
@CallSuper
public void onTrimMemory(int level) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
Object c = callbacks[i];
if (c instanceof ComponentCallbacks2) {
((ComponentCallbacks2)c).onTrimMemory(level);
}
}
}
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
//当应用所有UI隐藏时应该释放UI上所有占用的资源
if(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN == level)
GlideApp.get(this).clearMemory();
//根据level级别来清除一些图片缓存
GlideApp.get(this).onTrimMemory(level);
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
clearMemoryCache();
}
}
@Test
public void testBackgroundStateChangeCallbacksDontFire_AutomaticResourceManagementTurnedOff() {
FirebaseApp firebaseApp = FirebaseApp.initializeApp(targetContext, OPTIONS, "myApp");
firebaseApp.setAutomaticResourceManagementEnabled(true);
final AtomicInteger callbackCount = new AtomicInteger();
final AtomicBoolean backgroundState = new AtomicBoolean();
FirebaseApp.BackgroundStateChangeListener listener =
background -> {
backgroundState.set(background);
callbackCount.incrementAndGet();
};
firebaseApp.addBackgroundStateChangeListener(listener);
// App moves to the background.
backgroundDetector.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
assertThat(callbackCount.get()).isEqualTo(1);
// Turning off automatic resource management fires foreground event, if the current state
// is background.
assertThat(backgroundDetector.isInBackground()).isTrue();
firebaseApp.setAutomaticResourceManagementEnabled(false);
assertThat(callbackCount.get()).isEqualTo(2);
assertThat(backgroundState.get()).isFalse();
// No more callbacks.
backgroundDetector.onActivityResumed(null);
backgroundDetector.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
assertThat(callbackCount.get()).isEqualTo(2);
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
//当应用所有UI隐藏时应该释放UI上所有占用的资源
if(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN == level)
GlideApp.get(this).clearMemory();
//根据level级别来清除一些图片缓存
GlideApp.get(this).onTrimMemory(level);
}
@Override
public void onTrimMemory(int level) {
Log.w(TAG, "------------onTrimMemory level = " + level + " ----------------");
try {
if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) { // 60:后台,内存紧张
clearMemoryCaches();
} else if (level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {//15:前台,内存紧张
clearMemoryCaches();
}
} catch (Exception e) {
e.printStackTrace();
}
}