android - una - Error: Theme.Translucent & FLAG_ACTIVITY_REORDER_TO_FRONT
onsaveinstancestate android (6)
Tengo una actividad con el Tema translúcido:
android:theme="@android:style/Theme.Translucent.NoTitleBar"
También el problema se puede reproducir con solo este Tema:
<style name="MyTheme" parent="@android:style/Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackground">@null</item>
</style>
Esta actividad se carga al inicio y se guarda en la memoria (cuando comienzo esta actividad, FLAG_ACTIVITY_REORDER_TO_FRONT
indicador FLAG_ACTIVITY_REORDER_TO_FRONT
como extra).
Problema: cuando comienzo esta actividad (desde el menú), la actividad no aparece, no pasa nada. Pero: si elimino el tema translúcido: todo funciona bien, la actividad vuelve al frente.
Sí se llama a onNewIntent ().
¡Y si presiono hacia atrás la actividad translúcida es la siguiente! Pero tiene que ser el mejor.
Un ejemplo siendo
A (actividad translúcida) BC
Pila: A
A startActivity (B)
Pila: A, B
B startActivity (C)
Pila: A, B, C
c startActivity (A) // con la bandera FLAG_ACTIVITY_REORDER_TO_FRONT
La pila debe ser : B, C, A
pero A nunca se lleva al frente, aunque se llama onNewIntent ().
¿Algunas ideas?
Notas laterales
Interesante pregunta sin respuesta: http://groups.google.com/group/android-developers/browse_thread/thread/269c67f6b39cfe45?pli=1
android:launchMode
de singleTask
o singleInstance
no se desean utilizar. Estos cambian la backstack y mueven las actividades a su propia pila. Por lo tanto, ya no tenemos A, B, C.
singleTask y singleInstance: no son apropiados para la mayoría de las aplicaciones, ya que dan como resultado un modelo de interacción que probablemente no sea familiar para los usuarios y es muy diferente de la mayoría de las otras aplicaciones.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Cualquiera que quiera una representación visual de los launchModes prueba esta aplicación: https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode
launchMode
debe ser singleTask
en la etiqueta <activity>
de su actividad en el archivo de manifiesto.
De la documentación:
SingleTask: si al iniciar la actividad ya se está ejecutando una tarea que comienza con esta actividad, en lugar de comenzar una nueva instancia, la tarea actual se lleva al frente. La instancia existente recibirá una llamada a
Activity.onNewIntent()
con el nuevo Intent que se está iniciando y con el indicadorIntent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
establecido. Este es un superconjunto del modo singleTop, donde si ya hay una instancia de la actividad que se inicia en la parte superior de la pila, recibirá la intención tal como se describe allí (sin el indicadorFLAG_ACTIVITY_BROUGHT_TO_FRONT
establecido).
Actualizar
Como una mejor solución puede intentar invalidar toda la ventana en onNewIntent()
o en onResume
..
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
getWindow().getDecorView().invalidate();
}
Acabo de quitar el FLAG y todo está funcionando para mí. No hay ningún problema. La primera actividad sigue siendo transparente y sube a la cima cuando se te llama ... Solo inténtalo.
Aquí el código de mi ejemplo completo,
Primer acto
public class FirstAct extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("First Here Go To Second");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(FirstAct.this,SecondAct.class);
startActivity(intent);
}
});
setContentView(btn);
}
}
SecondAct
public class SecondAct extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("Second Here Go To Third");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(SecondAct.this,ThirdAct.class);
startActivity(intent);
}
});
setContentView(btn);
}
}
ThirdAct
public class ThirdAct extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("Third Here Go To First");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ThirdAct.this,FirstAct.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
});
setContentView(btn);
}
}
Editar actividad con LaunchMode SingleInsance * Manifest *
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mj.temp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".FirstAct" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:launchMode="singleInstance"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="SecondAct" android:launchMode="singleInstance"></activity>
<activity android:name="ThirdAct" android:launchMode="singleInstance"></activity>
</application>
</manifest>
Si no configuramos el tema desde AndroidManifest.xml, bloqueamos la actividad y establecemos el tema antes de setContentView, en el método onCreate en la primera actividad translúcida, el problema está resuelto, a continuación se muestra el código:
public class TranslucentActivityDemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTheme(R.style.myTheme);
setContentView(R.layout.main);
}
Aquí está mi idea de solución. Creo que el problema se desencadena al solicitar que una actividad translúcida en el backstack sea llevada al frente. Como no podemos hacer eso, comencemos una nueva copia de la actividad translúcida, pero en lugar de recrear completamente uno desde cero, reduzcamos la cantidad de trabajo utilizando un fragmento.
Entonces, si su actividad translúcida se veía así (copiada de la respuesta de MKJParekh):
public class FirstAct extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("First Here Go To Second");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(FirstAct.this, SecondAct.class);
startActivity(intent);
}
});
setContentView(btn);
}
}
Podemos convertirlo a algo como esto:
public class FirstAct extends FragmentActivity {
private static SavedState mSavedState;
private FirstFrag mFrag;
public static class FirstFrag extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Context context = inflater.getContext();
Button btn = new Button(context);
btn.setText("First Here Go To Second");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(context, SecondAct.class);
startActivity(intent);
}
});
return btn;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFrag = new FirstFrag();
if (mSavedState != null) mFrag.setInitialSavedState(mSavedState);
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mFrag)
.commit();
}
@Override
protected void onPause() {
super.onPause();
mSavedState = getSupportFragmentManager().saveFragmentInstanceState(mFrag);
finish();
}
}
Con este código, no necesitamos usar el indicador FLAG_ACTIVITY_REORDER_TO_FRONT
al iniciar FirstAct
más adelante, ya que en el fondo usará SavedState
de su copia anterior como estado inicial de la nueva copia.
Tenga en cuenta que en mi código de ejemplo anterior simplemente destruí la copia anterior de FirstAct
(llamando a finish()
después de guardar el estado de la instancia del fragmento) en su onPause()
. Una implementación más seria probablemente establecería un indicador en su lugar (para ser registrado en onResume()
) si una copia en particular debe finish()
ed cuando se vuelve a visitar en la pila (si ha sido "presentada al frente" como una copia más reciente) .
Yo tuve el mísmo problema. Moví la etiqueta de permiso de usos antes de la etiqueta de la aplicación en AndroidManifest.xml. Eso lo solucionó para mí.
Como solución no es una respuesta
He hecho esto:
public class OverlayActivity extends Activity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// Restart self when attempting to be brought to front
Intent restartIntent = new Intent(this, OverlayActivity.class);
startActivity(restartIntent);
finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overlay);
}
}
si alguien puede darme una respuesta, ¡ellos ganan la bonificación brucey!