Se detectó pérdida de memoria en las pestañas personalizadas de Chrome
Estoy intentando implementar las pestañas personalizadas de Chrome y detectar una pérdida de memoria a través de LeakCanary.
La aplicación de demostración no parece tener fugas a menos que MainActivity
otra capa de actividad (es decir, MainActivity
lanza Activity2
, que enlaza / desvincula al servicio de pestaña personalizada y lanza la url – todo lo que hace MainActivity
en la aplicación de demostración ).
- Android Weak Referencia de la clase interna
- ¿Está declarando una clase interna en una vista peligrosa?
- Java.lang.OutOfMemoryError: android.support.v4.app.BackStackState de longitud 1279544898 se desbordaría
- View.getViewTreeObserver (). AddOnGlobalLayoutListener Fragmento de fugas
- ProgressDialog: cómo evitar la ventana filtrada
MainActivity se parece a esto:
public class MainActivity extends Activity implements OnClickListener { private Button mLaunchButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LeakCanary.install(getApplication()); setContentView(R.layout.main); mLaunchButton = (Button) findViewById(R.id.launch_button); mLaunchButton.setOnClickListener(this); } @Override public void onClick(View v) { int viewId = v.getId(); if (viewId == R.id.launch_button) { Intent intent = new Intent(getApplicationContext(), Activity2.class); startActivity(intent); } } }
Volver de Activity2
a MainActivity
causará esta fuga:
09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ In org.chromium.customtabsclient.example:1.0:1. 09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * org.chromium.customtabsclient.Activity2 has leaked: 09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * GC ROOT android.support.customtabs.CustomTabsClient$1.val$callback (anonymous class extends android.support.customtabs.ICustomTabsCallback$Stub) 09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * references org.chromium.customtabsclient.Activity2$2.this$0 (anonymous class extends android.support.customtabs.CustomTabsCallback) 09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * leaks org.chromium.customtabsclient.Activity2 instance
Https://gist.github.com/abvanpelt/ddbc732f31550b09fc27
Mi pregunta es: ¿esto es un error en la aplicación de demostración? (¿Tal vez unbindCustomTabsService()
falta algún desmontaje necesario?) ¿O esto es un error en la propia biblioteca Chrome Custom Tabs?
Gracias.
- Fragmentos de Android en Backstack ocupan demasiada memoria
- ¿Es esta una forma válida de mantener una referencia estática y Actividad / Contexto? ¿Por qué no debo hacer esto?
- MapView v2 manteniendo el contexto alrededor
- Informe Leakcanary de pérdida de memoria usando Otto
- Fuga de memoria en Android al intentar enviar un formulario con imagen al servidor PHP
- ¿Se filtra siempre la primera instancia de MapActivity?
- ¿Cuáles son los beneficios de usar WeakReferences?
- Kotlin: safe lambdas (no hay fugas de memoria)?
MainActivity en el ejemplo crea una instancia de CustomTabsServiceConnection y CustomTabsCallback como clases internas anónimas.
Si las cambia a clases internas estáticas, por lo tanto, quitando this
referencia a MainActivity, y establecer las referencias a MainActivity como WeakReferences, verá que LeakCanary deja de informar sobre la filtración de MainActivity.
Ahora, es posible que todavía vea el informe canary de fugas acerca de la fuga de ServiceConnection si lo configura para ver ese objeto. La razón es que está vinculada al servicio Chrome y no puede ser limpiada por GC hasta que GC también se ejecute en el lado del servidor.
He creado una prueba que enlaza y desvincula el servicio en un bucle y he confirmado que las ServiceConnections están siendo recopiladas después de un tiempo.
Por lo tanto, se puede mejorar la demostración para evitar que ServiceConnection contenga una referencia a MainActivity, evitando tener un objeto pesado como una actividad que esté viva mucho tiempo después de que el servicio está desconectado y no es un problema con la biblioteca de pestañas personalizadas.
Encontrado la respuesta para esta pregunta –
Si está iniciando customTab como sigue
private void launchChromeCustomTab(final Context context, final Uri uri) { mServiceConnection = new CustomTabsServiceConnection() { @Override public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient client) { client.warmup(0L); final CustomTabsIntent intent = new CustomTabsIntent.Builder().build(); intent.launchUrl(context, uri); mIsCustomTabsLaunched = true; } @Override public void onServiceDisconnected(ComponentName name) { } }; CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", mServiceConnection); }
A continuación, debe desvincular este método mServiceConnection onDestroy como –
@Override protected void onDestroy() { super.onDestroy(); this.unbindService(mServiceConnection); mServiceConnection = null; }
Eso dejará de lanzar
android.app.ServiceConnectionLeaked: Activity <Your_Activity> has leaked ServiceConnection
- Variables en los recursos XML: pasa valores de padres a hijos
- ¿Cómo depurar el navegador nativo de Android (no Chrome) en una máquina de escritorio?