¿Es posible obtener recursos dentro de un bloque de contexto estático?
Quiero crear una tabla hash estática para convertir cadenas a enteros . La advertencia aquí es que quiero usar las cadenas que he definido como recursos en varias listas en archivos XML .
Puedo escribir esto, usando solamente identificaciones de los recursos:
- Android Lint - Cómo ocultar una advertencia 'El recurso Xxx parece no estar utilizado'
- ¿Qué significa exactamente usar el contexto de aplicación?
- La razón de los activos y recursos crudos en Android
- Android strings.xml ¿Buenas prácticas?
- Obtención dinámica de los idiomas disponibles de la aplicación
public class MyActivity extends Activity { private static Map<Integer, Integer> views = new HashMap<Integer, Integer>(); static { views.put(R.string.full_text, MessageTable.VIEW_FULL); views.put(R.string.only_text, MessageTable.VIEW_MSG); views.put(R.string.tag_text, MessageTable.VIEW_TAGMSG); }
No tengo errores, pero lo que realmente necesito hacer es algo como esto:
public class MyActivity extends Activity { private static Map<String, Integer> views = new HashMap<String, Integer>(); static { views.put(getResources().getString(R.string.full_text), MessageTable.VIEW_FULL); views.put(getResources().getString(R.string.only_text), MessageTable.VIEW_MSG); views.put(getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG); }
Que me da el siguiente error en Eclipse:
Cannot make a static reference to the non-static method getResources() from the type ContextWrapper
El mensaje tiene sentido, pero lo que no tiene sentido es que los recursos son inalcanzables desde el bloque estático, se podría pensar que las variables estáticas fueron creadas para hacer uso de los recursos.
Supongo que puedo poblar la tabla hash durante el constructor de objetos, pero esto significaría hacerlo en el lugar equivocado.
- ¿Por qué setImageResource no muestra nada?
- ¿Cómo referenciar una cadena de otro paquete en una biblioteca usando XML en Android?
- ¿Qué límites hay en el número de recursos de Android?
- Resumen de la tabla de referencia local de JNI (512 entradas)
- Android.content.res.Resources $ NotFoundException: ID de recurso de cadena
- Cómo obtener una matriz de bytes de un recurso extraíble?
- La base de datos no se copia correctamente en OnePlus Two
- ¿No puede anular el recurso xml de la biblioteca con el recurso png en la aplicación?
getResources()
(abreviatura de ~ MyActivity.this.getResources()
) requiere un objeto de contexto que no se inicialice en ese momento. Dado que el contexto sólo está disponible después de pulsar en onCreate
, ni siquiera puede hacerlo en el momento de la construcción de MyActivity
.
La razón es que el gestor de actividades que instancia tu clase MyActivity
tiene que determinar la configuración (orientación, tamaño de pantalla, idioma, …) antes de saber qué recursos deben extraerse del xml. -> Los recursos no son estáticos y no se puede acceder desde el contexto estático.
Así que supongo que no hay manera de hacer esas operaciones en onCreate
o más tarde.
Edit: Aunque ciertamente puede actualizar el HashMap estático (o un Context
estático) de onCreate
no recomendaría que ya que puede tener varias instancias de la misma Actividad con configuraciones posiblemente diferentes / cambiantes. También almacenar un Context
estático es una gran manera de crear un escape de memoria
public Static Resources mResources; public MyApplication extends Application { @Override public void onCreate() { mResources = getResources(); } }
Una vez que tenga la referencia estática a los recursos, puede referirse a ella desde la aplicación completa. Sin embargo, no estoy seguro de si esto va a introducir una fuga momory o no;
Una cosa que puedes hacer es crear una clase de Application
y registrarla en tu AndroidManifest.xml. A continuación, anule el método onCreate y establezca la clase Application como una referencia estática y, a continuación, toque la clase Activity para ejecutar el inicializador estático. La clase de Application
se ejecutará como el apk se carga en la memoria por lo que siempre se ejecutará antes de cualquier Activity
.
Hay algunos inconvenientes significativos a esto. La más obvia creo que pienso que es si el sistema cambia de idioma y usted ha agregado traducciones a estos recursos; Entonces tendrá cadenas inconsistentes porque la aplicación utilizará el valor predeterminado / lo que sea el idioma cuando se inició la aplicación. Los recursos de cadenas están influenciados por el sistema de administración de recursos de Android, por lo que los cambios en cosas como la orientación, el lenguaje del sistema y las dimensiones de la pantalla pueden influir en estos valores. Esas son las razones por las que las actividades se restablecen cuando
En resumen, es mejor utilizar pares de clave-valor Strings constantes para este trabajo. Si necesita usar recursos de cadena para poder manejar mejor las traducciones. Los cargaría cada vez que comenzara la Actividad. De lo contrario se corre el riesgo de pérdidas de memoria y traducciones de cadena inconsistentes.
public MyApplication extends Application { public static Context GlobalContext = null; @Override protected void onCreate() { MyApplication.GlobalContext = this; // Touch the activity class. MyActivity activity = new MyActivity(); // Throw it away by not using it. // invalidate handle to prevent GC leaks. GlobalContext = null; } } public class MyActivity extends Activity { private static Map<String, Integer> views = new HashMap<String, Integer>(); static { Context context = MyApplication.GlobalContext; Resources res = context.getResources(); views.put(res.getString(R.string.full_text), MessageTable.VIEW_FULL); views.put(res.getString(R.string.only_text), MessageTable.VIEW_MSG); views.put(res.getString(R.string.tag_text), MessageTable.VIEW_TAGMSG); } }
Siempre puede mantener una referencia estática a ApplicationContext. Una manera posible se describe aquí: ¿ Forma estática de obtener 'Contexto' en Android?
No sé cuál es la MEJOR manera, pero, por ejemplo, en mi aplicación, tengo un Singleton (llamado GuiaUtil) que aways mantiene mi Actividad y Contexto actuales.
private static Map<String, Integer> views = new HashMap<String, Integer>(); static { views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.full_text), MessageTable.VIEW_FULL); views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.only_text), MessageTable.VIEW_MSG); views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG); }
- Desvío de llamadas de android mediante programación
- Dispositivo virtual de genymotion statred pero pantalla blanca …?