Estoy tratando de usar getString() para obtener una Cadena de recursos para asignar a una matriz de Cadena antes de que mi actividad es creada:

private static final String[] MenuNames = {
    Resources.getSystem().getString(R.string.LCMeterMenu),
    Resources.getSystem().getString(R.string.FrecMenu),
    Resources.getSystem().getString(R.string.LogicAnalyzerMenu),
    "Prueba con achartengine",
    Resources.getSystem().getString(R.string.BrazoMenu)
};

Cuando yo uso Resources.getSystem().getString(R.string.LCMeterMenu), Eclipse no se queja pero me da un error en tiempo de ejecución:

Causada por: android.contenido.res.Recursos$NotFoundException: String Resource ID #0x7f0a000a

Pero si pongo dentro de onCreate():

Log.i("StringR", "String: " + getString(R.string.LCMeterMenu));

Recibo la Cadena pero no puedo asignar a la Cadena final he definido antes. Si yo sólo uso getString() antes de onCreate() me llega la estática mensaje de error. ¿Cómo puedo utilizar los recursos antes de onCreate() para las variables globales?

usted tiene intente Cadena getResources().getString(R.string.LCMeterMenu); en lugar de Resources.getSystem().getString(R.string.LCMeterMenu)
¿Por qué quieres declarar la matriz final. ¿Por qué no puede declarar la matriz como privada estática y inicializar el array en onCreate().
Porque la matriz no va a cambiar a lo largo de la ejecución de la Actividad, ¿no es mejor usar la final ?
si usted desea, usted puede usarlo de esta manera. final String[] sa = new String[n]; como desee llenar la matriz con las cadenas de recursos sabes valor de n. y, a continuación, en el onCreate de actualización como. sa[0] = resourceString1; etc..,recuerde que usted puede cambiar los valores en, o decir de rellenar la Matriz cada vez que desee, incluso si su declarada como final.

OriginalEl autor Andres | 2012-09-20

5 Comentarios

  1. 27

    No se puede inicializar un static final campo de los recursos; el campo debe ser inicializadas en el momento de la clase se inicializa y que pasa antes de la aplicación de los recursos se han enlazado en tiempo de ejecución. (Por cierto, la razón por la que no se puede utilizar Resources.getSystem() es que el Resources objeto de obtener de esa manera sólo contiene los recursos del sistema, no de los recursos de la aplicación.)

    Si necesitas esas cadenas disponibles antes de la aplicación de los recursos están vinculados, la única práctica que hay que hacer es poner las cadenas en el código directamente. Sin embargo, el «Android» de manera sería organizar el código para la inicialización sólo debe suceder durante (o después) de onCreate(). Sólo inicializar la matriz de cadena en onCreate() y no te preocupes por hacer los campos estáticos o final.

    Si usted no desea que la matriz de cadena de estar asociados con una actividad en particular, entonces usted puede subclase Application y leer la matriz de los recursos dentro de la clase de aplicación onCreate() método. (También deberá declarar su aplicación personalizada de la clase en el manifiesto.) Sin embargo, el docs recomendar en contra de dicho enfoque. (Ya que la matriz es privado, sospecho que está estrechamente ligada a una sola actividad de todos modos, por lo que el uso de un Application subclase no parece justificada.)

    Una alternativa es declarar una clase singleton para su matriz. El singleton función de descriptor de acceso, a continuación, necesita un Context para que pueda recuperar los recursos si es necesario:

    public class StringArray {
        private static String[] theArray;
        public static String[] getArray(Context context) {
            if (theArray == null) {
                theArray = context.getResources().getStringArray(R.array.my_strings);
            }
            return theArray;
        }
    }

    (Esto supone que la cadena de datos se definen en un <string-array> de recursos como @JaiSoni sugirió en su respuesta.) Una vez más, el campo de miembro no se puede declarar final.

    No se puede encontrar @JaiSoni la respuesta aquí…
    Veo que JaiSoni eliminado la respuesta. La misma información se puede encontrar en la documentación aquí en cadena de la matriz de recursos.
    Tenga en cuenta que puede asignar un campo estático en onCreate(), simplemente no tiene un valor útil previamente. Y si el valor asignado puede ser diferente en una ejecución posterior, que puede «confundir» a otras instancias que comparten.

    OriginalEl autor Ted Hopp

  2. 4

    No, usted no puede utilizar los Recursos antes de onCreate(). Usted puede obtener la instancia de Recursos en onCreate() mediante getResources() donde usted puede conseguir todas las Cadenas. También las cadenas ya están declarados como static, al definir en el strings.xml.

    Pseudo código para acceder a los Recursos,

    Resources res = getResources();
    String app_name = res.getString(R.string.app_name);
    Si yo uso getResources().getString() obtengo: «No se puede hacer una referencia estática para el método no estático getResources() del tipo ContextWrapper»
    He editado y añadido código de pseudo cómo acceder a
    Sí, he intentado de esa manera y funciona, pero tengo que eliminar la palabra clave static creo que voy a tener que eliminar la estática o final no hay otro modo a como yo lo veo.

    OriginalEl autor Lalit Poptani

  3. 3

    Otro enfoque podría ser para inicializar la matriz estática con identificadores de recursos (que ya están disponibles en contraposición a los recursos propios).

    private static final int[] MenuNames = {
        R.string.LCMeterMenu,
        R.string.FrecMenu,
        ...
    };

    De esta manera, usted puede retrasar la carga de recursos, cuando en realidad están disponibles:

    String s = getResources().getString(MenuNames[i]);

    OriginalEl autor bompf

  4. 1

    El siguiente es un enfoque de trabajo para inicializar static final variables en android desde XML, tales como strings.xml.

    1. Subclase de la aplicación y proporcionar un «contexto estático»
    2. Registro de la clase de aplicación en el manifiesto de
    3. Uso del contexto estático para inicializar sus constantes

    1. MyApplication.java

    public abstract class MyApplication extends Application {
    
        private static Context context;
    
        @Override
        public void onCreate() {
            super.onCreate();
            context = getApplicationContext();
        }
    
        /**
         * Returns a "static" application context. Don't try to create dialogs on
         * this, it's not gonna work!
         * 
         * @return
         */
        public static Context getContext() {
            return context;
        }
    }

    2. AndroidManifest.xml

    <application
        android:name=".android.application.MyApplication"
        <!-- ... -->
    </application>

    3. El código de la aplicación, por ejemplo, la Actividad

    private static final String[] MenuNames = {
        getContext().getString(R.string.LCMeterMenu),
        getContext().getString(R.string.FrecMenu),
        getContext().getString(R.string.LogicAnalyzerMenu),
        "Prueba con achartengine",
        getContext().getString(R.string.BrazoMenu)
    };
    protected static Context getContext() {
        return MyApplication.getContext();
    }

    Para el trabajo de los ejemplos se refieren a AbstractApplication y PreferencesServiceSharedPreferences.

    Tenga en cuenta que este enfoque también tiene sus desventajas:

    • Aparte de que se opone a la de «Android» (como @Ted Hopp sugerido en su respuesta),
    • hace que la prueba un poco difícil. Es por eso que la llamada a MyApplication.getContext() está envuelto en otro método. Como se trata de un método estático, primordial en las pruebas de código no es simple. Pero se puede usar un framework como Powermock para este propósito.
    • Además es un poco propenso a NullPointerExceptions. Tan pronto como el contexto es null (por ejemplo, en su código de prueba) el código de la aplicación se bloquea. Una opción para superar esto, es para realizar la inicialización de un constructor, donde se podía reaccionar a getContext()regresar null (ver ejemplo).

    OriginalEl autor schnatterer

  5. 0

    Lo que se obtiene por la getString(int resId) ya será una constante en su aplicación. ¿Por qué mantenerlo en otro final static variable. Usted puede leerlo como que cada vez que desee, haga?

    ¿No es la manera correcta de usar mi Cadena si es que no va a cambiar a lo largo de mi la ejecución de la Actividad ? Mejor desempeño también ? Soy nuevo en Java por lo que estoy aprendiendo 🙂
    Si usted tiene un montón de casos donde estaría llamando la getResources().getString() método, para luego hacer la inicialización en el onCreate() método y hacer que su variable estática. Esa es mi opinión.
    «¿Por qué mantenerlo en otra final de la variable estática». Porque el uso de static final STRING_CONSTANT le da más legible el código. Por ejemplo: la televisión.setText(STRING_CONSTANT) frente a la tv.setText(getString(R. string.string_constant))

    OriginalEl autor midhunhk

Dejar respuesta

Please enter your comment!
Please enter your name here