Quiero leer cadenas de caracteres de un xml archivo antes de hacer cualquier otra cosa, como setText de los widgets, así que, ¿cómo puedo hacer eso sin una actividad objeto de llamada getResources() en?

InformationsquelleAutor lost baby | 2010-12-08

12 Comentarios

  1. 363
    1. Crear una subclase de Aplicación, por ejemplo public class App extends Application {
    2. Conjunto de la android:name atributo de su <application> etiqueta en la AndroidManifest.xml a punto a su nueva clase, por ejemplo, android:name=".App"
    3. En el onCreate() método de la instancia de la aplicación, guardar su contexto (por ejemplo,this) a un campo estático llamado mContext y crear un método estático que se devuelve este campo, por ejemplo,getContext():

    Esta es la forma en que debe buscar:

    public class App extends Application{
    
        private static Context mContext;
    
        @Override
        public void onCreate() {
            super.onCreate();
            mContext = this;
        }
    
        public static Context getContext(){
            return mContext;
        }
    }

    Ahora usted puede utilizar: App.getContext() cuando usted desea conseguir un contexto y, a continuación, getResources() (o App.getContext().getResources()).

    • buen truco, gracias. ok, así que no hay una norma api entonces?
    • Eso es normal, no es un truco XD
    • Estoy de acuerdo en que este es un feo corte. Uno nunca debe asignar valores dinámicos para el objeto estático
    • No son los valores dinámicos. Estamos hablando acerca de la configuración de constantes estáticas a través de los recursos. Por el contrario, creo que, el problema de esta forma es que no podemos utilizar estas constantes como estática para toda la clase de aplicación, incluso si SON estáticos para toda la clase de aplicación. Pero el 99% de los problemas pueden resolverse de esta manera. +1 a Cristian!
    • Ejemplo de la aplicación no es un valor dinámico, ¿cómo es eso @Gangnus? En cualquier caso, he encontrado la manera difícil que depender de la estática en Android no es nada, pero el dolor de cabeza. «Ahora la ves, ahora no»
    • 1. Oh, sí, prácticamente, por la realización que ellos son dinámicos, o déjenos mejor decir, instancia constantes. De la instancia de Solicitud. Pero relativamente a las actividades y, por supuesto, a setText y tal, como en la pregunta, que se podría configurar de forma estática – es decir, después de esta respuesta puede tener como constantes de pertenencia a un descendiente de la clase de Actividad. 2. Las variables estáticas funciona bien en Android. El problema es que si usted desea utilizar algunos recursos como los valores para la Aplicación estática de variables/constantes, es imposible. Usted tiene sólo dos en parte de las soluciones, dado como respuestas aquí.
    • De los que no puedo evitar pensar que este es un ‘hack’. Aunque la estoy usando (por cierto, gracias por dar esta solución, ya que yo estaba a punto de externalizar la localización) que tengo este mal presentimiento, como esto está mal de alguna manera.
    • Mejor o peor que acaba de pasar en un Contexto como el primer parámetro de cada método estático en su aplicación? El ex siente chapucero, pero el último es innecesariamente repetitivo.
    • Los médicos dicen que «normalmente no es necesario para la subclase de la Aplicación. En la mayoría de las situaciones, la estática de los embarazos únicos pueden proporcionar la misma funcionalidad de una forma más modular. Si su singleton necesidades de un contexto global (por ejemplo, para registrar los receptores de difusión), la función para recuperar puede ser dentro de un Contexto que internamente usa el Contexto.getApplicationContext() cuando la construcción del singleton.» ~developer.android.com/reference/android/app/Application.html
    • para «ahora mis clases se ve bastante normal»! la misma sensación que en este caso!
    • Este debe ser un wiki de los wikis… me refiero a que en ningún lugar se especifica y que mantiene mi patrón MVP muy limpio. Para mí funciona en el SDK de 19>22
    • Usted debe leer esto: stackoverflow.com/a/21336200/2016562 y la épica de blog sobre el Contexto escrito por Dave Smith
    • Para evitar fugas de memoria sería mejor tienda, en un Contexto de WeakReference: private static WeakReference<Contexto> mContext; public static Contexto getContext(){ return mContext.get(); } Esto debería ayudar cuando la aplicación se bloquea y no se puede establecer el contexto estático a null (WeakReference puede ser recolector de basura).
    • Pero que apunte a sí mismo, ¿por qué necesitamos almacenar en un WeakReference?
    • Eso depende de donde usted está llamando el contexto de la tarde, pero estoy de acuerdo en que es probablemente más seguro.
    • ¿cómo fijar mContext = this; en onCreate()? Da error.
    • Estoy usando este código en el onCreate(): mContext = new WeakReference<Contexto>(este); Espero que sea de ayuda para usted.
    • ¿Cómo podría haber una pérdida de memoria ? El AppContext ES el objeto de Aplicación.
    • sí, es una especie de «pre-filtrado» en fin…. como un Singleton… simplemente no aferrarse a ese Contexto de la Aplicación en un lugar donde no debería… entonces usted tiene un mayor potencial de llegar a las fugas de memoria.
    • Necesitaba establecer la aplicación de la etiqueta el atributo name = «.App» en el manifiesto para que esta solución funcione. Es decir, la aplicación <aplicación android:name=».App» …

  2. 98

    Uso

    Resources.getSystem().getString(android.R.string.cancel)

    Puede utilizar en todas partes en su aplicación, incluso en las constantes estáticas de declaraciones!
    Pero para los recursos del sistema sólo!

    • Eso es genial. Yo por lo general no se sienten ofendidos… justo cuando alguien usa mayúsculas 😛 es broma. Así, sus obras de algunos recursos, como las cadenas y dibujables… sin embargo, como la documentación que se dice, no funciona bien para cosas como medidas de orientación, etc. También, y más importante, esto no va a permitir que usted consiga un contexto global que es útil a veces para las cosas que lo necesiten (levantando una Toast por ejemplo, la obtención de un SharedPreference ejemplo, abrir una base de datos, como mi lengua latina maestro dice: etc).
    • Usted no puede incluso ganar la paz en todo el mundo por ella :-). Pero ayuda a resolver el problema planteado por la pregunta aquí. No estoy diciendo que resuelve cada una de las tareas, que resuelva su tarea casi en cada lugar de la aplicación. He buscado una solución de 10 meses – todo el tiempo que yo uso Android. Y ahora que lo he encontrado.
    • Usted tiene que tener cuidado aquí. No trate de encontrar la aplicación de los recursos que utiliza este método. Lea la impresión fina: Devolver un global de los Recursos compartidos objeto que proporciona el acceso sólo a los recursos del sistema (no de la aplicación de los recursos), y no está configurado para la pantalla actual (no se puede usar la dimensión de las unidades, no cambio basado en la orientación, etc).
    • Cita: «Pero para los recursos del sistema sólo!». Sé /*suspiro/*
    • Tengo una excepción el uso que: android.contenido.res.Recursos$NotFoundException: String IDENTIFICADOR de recurso
    • Esto es muy extraño. Mejor publicar una pregunta al respecto.

  3. 3

    El Singleton:

    package com.domain.packagename;
    
    import android.content.Context;
    
    /**
     * Created by Versa on 10.09.15.
     */
    public class ApplicationContextSingleton {
        private static PrefsContextSingleton mInstance;
        private Context context;
    
        public static ApplicationContextSingleton getInstance() {
            if (mInstance == null) mInstance = getSync();
            return mInstance;
        }
    
        private static synchronized ApplicationContextSingleton getSync() {
            if (mInstance == null) mInstance = new PrefsContextSingleton();
            return mInstance;
        }
    
        public void initialize(Context context) {
            this.context = context;
        }
    
        public Context getApplicationContext() {
            return context;
        }
    
    }

    Inicializar el Singleton en su Application subclase:

    package com.domain.packagename;
    
    import android.app.Application;
    
    /**
     * Created by Versa on 25.08.15.
     */
    public class mApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            ApplicationContextSingleton.getInstance().initialize(this);
        }
    }

    Si no estoy equivocado, esto le da un gancho de applicationContext en todas partes, llame a con ApplicationContextSingleton.getInstance.getApplicationContext();
    Usted no debe necesitar para borrar en cualquier momento, como cuando la aplicación se cierra, esto va con él de todos modos.

    Recuerde que la actualización de AndroidManifest.xml para utilizar este Application subclase:

    <?xml version="1.0" encoding="utf-8"?>
    
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.domain.packagename"
        >
    
    <application
        android:allowBackup="true"
        android:name=".mApplication" <!-- This is the important line -->
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:icon="@drawable/app_icon"
        >

    Ahora usted debería ser capaz de utilizar ApplicationContextSingleton.getInstance().getApplicationContext().getResources() desde cualquier lugar, además de los muy pocos lugares donde subclases de la aplicación cant.

    Por favor, hágamelo saber si usted ve algo mal aquí, gracias. 🙂

  4. 3

    También hay otra posibilidad. Me carga shaders de OpenGl de recursos como este:

    static private String vertexShaderCode;
    static private String fragmentShaderCode;
    
    static {
        vertexShaderCode = readResourceAsString("/res/raw/vertex_shader.glsl");
        fragmentShaderCode = readResourceAsString("/res/raw/fragment_shader.glsl");
    }
    
    private static String readResourceAsString(String path) {
        Exception innerException;
        Class<? extends FloorPlanRenderer> aClass = FloorPlanRenderer.class;
        InputStream inputStream = aClass.getResourceAsStream(path);
    
        byte[] bytes;
        try {
            bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            return new String(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            innerException = e;
        }
        throw new RuntimeException("Cannot load shader code from resources.", innerException);
    }

    Como usted puede ver, usted puede tener acceso a cualquier recurso en la ruta /res/...
    Cambio aClass a su clase. Esto también cómo puedo cargar recursos en pruebas (androidTests)

    • La única solución que funcionó para mí al no tener una Actividad (desarrollo de un plugin sin una clase que podría extender la Aplicación). Gracias +1
  5. 2

    Otra solución:

    Si usted tiene una estática subclase en un no-estática exterior de la clase, usted puede tener acceso a los recursos dentro de la subclase a través de las variables estáticas en el exterior de la clase, que se activa en la creación de la clase exterior. Como

    public class Outerclass {
    
        static String resource1
    
        public onCreate() {
            resource1 = getString(R.string.text);
        }
    
        public static class Innerclass {
    
            public StringGetter (int num) {
                return resource1; 
            }
        }
    }

    Yo lo he utilizado para el getPageTitle(int posición) Función de la estática FragmentPagerAdapter dentro de mi FragmentActivity que es útil debido a I8N.

  6. 2

    Acceso directo

    Yo uso App.getRes() en lugar de App.getContext().getResources() (como @Cristian respondió)

    Es muy simple de usar en cualquier lugar en el código!

    Así que aquí es un única solución por el cual usted puede tener acceso a los recursos desde cualquier lugar como Util class .

    (1) Crear o Editar su Application clase.

    import android.app.Application;
    import android.content.res.Resources;
    
    public class App extends Application {
        private static App mInstance;
        private static Resources res;
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            mInstance = this;
            res = getResources();
        }
    
        public static App getInstance() {
            return mInstance;
        }
    
        public static Resources getResourses() {
            return res;
        }
    
    }

    (2) Agregue el campo nombre de su manifest.xml <application etiqueta. (u Omitir este si ya existe)

    <application
            android:name=".App"
            ...
            >
            ...
        </application>

    Ahora que son buenos para ir.

    Uso App.getRes().getString(R.string.some_id) en cualquier lugar en el código.

  7. 0

    Creo que, más camino es posible.
    Pero a veces, yo con esta solución. (global):

        import android.content.Context;
    
        import <your package>.R;
    
        public class XmlVar {
    
            private XmlVar() {
            }
    
            private static String _write_success;
    
            public static String write_success() {
                return _write_success;
            }
    
    
            public static void Init(Context c) {
                _write_success = c.getResources().getString(R.string.write_success);
            }
        }
    //After activity created:
    cont = this.getApplicationContext();
    XmlVar.Init(cont);
    //And use everywhere
    XmlVar.write_success();
  8. 0

    En su clase, donde se implemente el estática función, usted puede llamar a un privado\públicas método de esta clase. El privado\método público puede acceder a la getResources.

    por ejemplo:

    public class Text {
    
       public static void setColor(EditText et) {
          et.resetColor(); //it works
    
          //ERROR
          et.setTextColor(getResources().getColor(R.color.Black)); //ERROR
       }
    
       //set the color to be black when reset
       private void resetColor() {
           setTextColor(getResources().getColor(R.color.Black));
       }
    }

    y de otra clase\actividad, puede llamar a:

    Text.setColor('some EditText you initialized');
  9. 0

    Me carga shader para openGL ES de función estática.

    Recuerde que usted debe utilizar minúsculas para su archivo y el nombre del directorio, o de lo contrario la operación se ha fallado

    public class MyGLRenderer implements GLSurfaceView.Renderer {
    
        ...
    
        public static int loadShader() {
            //   Read file as input stream
            InputStream inputStream = MyGLRenderer.class.getResourceAsStream("/res/raw/vertex_shader.txt");
    
            //   Convert input stream to string
            Scanner s = new Scanner(inputStream).useDelimiter("\A");
            String shaderCode = s.hasNext() ? s.next() : "";
        }
    
        ...
    
    }
  10. 0
    public Static Resources mResources;
    
     @Override
         public void onCreate()
         {
               mResources = getResources();
         }
    • Bueno, el problema es, getResources() necesita un contexto. Así que esto probablemente no es realmente un soltution para «sin una actividad objeto» (en la que se publicó el onCreate() método)
  11. 0

    Estoy utilizando la API de nivel 27 y encontrar una mejor solución después de luchar durante alrededor de dos días. Si quieres leer un archivo xml a partir de una clase que no se derivan de la Actividad o de la Aplicación, a continuación, haga lo siguiente.

    1. Poner el testdata.xml archivo dentro del directorio de activos.

    2. Escribir el siguiente código para obtener el testdata documento analiza.

          InputStream inputStream = this.getClass().getResourceAsStream("/assets/testdata.xml");
      
          //create a new DocumentBuilderFactory
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          //use the factory to create a documentbuilder
          DocumentBuilder builder = factory.newDocumentBuilder();
          //create a new document from input stream
          Document doc = builder.parse(inputStream);
  12. -1

    si usted tiene un contexto, me refiero a dentro;

    public void onReceive(Context context, Intent intent){
    
    }

    usted puede utilizar este código para obtener los recursos:

    context.getResources().getString(R.string.app_name);
    • El título de la pregunta, dice en un contexto estático. Que su respuesta no cubre.

Dejar respuesta

Please enter your comment!
Please enter your name here