it-swarm.com.de

Wie kann ich einen Ressourceninhalt aus einem statischen Kontext erhalten?

Ich möchte Strings aus einer xml-Datei lesen, bevor ich etwas anderes wie setText für Widgets erledige. Wie kann ich das tun, ohne dass ein Aktivitätsobjekt getResources() aufruft?

148
lost baby
  1. Erstellen Sie eine Unterklasse von ApplicationNAME _ , zum Beispiel public class App extends Application {
  2. Setzen Sie das Android:name -Attribut Ihres <application> -Tags im AndroidManifest.xml, um auf Ihre neue Klasse zu verweisen, z. Android:name=".App"
  3. Speichern Sie in der Methode onCreate() Ihrer App-Instanz Ihren Kontext (z. B. thisname__) in einem statischen Feld mit dem Namen mContextund erstellen Sie eine statische Methode, die dieses Feld zurückgibt, z. getContext():

So sollte es aussehen:

public class App extends Application{

    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    public static Context getContext(){
        return mContext;
    }
}

Jetzt können Sie Folgendes verwenden: App.getContext(), wann immer Sie einen Kontext abrufen möchten, und dann getResources() (oder App.getContext().getResources()).

363
Cristian

Benutzen

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

Sie können sie überall in Ihrer Anwendung verwenden, selbst in Deklarationen statischer Konstanten! Aber nur für Systemressourcen!

97
Gangnus

Es gibt auch eine andere Möglichkeit. Ich lade OpenGl-Shader aus folgenden Ressourcen:

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);
}

Wie Sie sehen, können Sie auf jede Ressource im Pfad /res/....__ zugreifen. Ändern Sie aClass in Ihre Klasse. Dies auch wie ich Ressourcen in Tests lade (androidTests)

3
Gregory Stein

The 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;
    }

}

Initialisieren Sie das Singleton in Ihrer Application-Unterklasse:

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);
    }
}

Wenn ich mich nicht irre, haben Sie überall einen Link zu applicationContext. Rufen Sie es mit ApplicationContextSingleton.getInstance.getApplicationContext();.__ auf. Sie sollten dies an keiner Stelle löschen, da beim Schließen der Anwendung dies sowieso damit einhergeht.

Denken Sie daran, AndroidManifest.xml zu aktualisieren, um diese Application-Unterklasse zu verwenden:

<?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"
    >

Jetzt sollten Sie ApplicationContextSingleton.getInstance (). GetApplicationContext (). GetResources () von überall aus verwenden können, auch an den wenigen Stellen, an denen Anwendungsunterklassen nicht funktionieren.

Bitte lassen Sie mich wissen, wenn Sie hier etwas Falsches sehen, danke. :)

3
Versa

Eine andere Lösung:

Wenn Sie eine statische Unterklasse in einer nicht statischen äußeren Klasse haben, können Sie von der Unterklasse aus über statische Variablen in der äußeren Klasse auf die Ressourcen zugreifen, die Sie beim Erstellen der äußeren Klasse initialisieren. Mögen

public class Outerclass {

    static String resource1

    public onCreate() {
        resource1 = getString(R.string.text);
    }

    public static class Innerclass {

        public StringGetter (int num) {
            return resource1; 
        }
    }
}

Ich habe es für die getPageTitle (int position) -Funktion des statischen FragmentPagerAdapter innerhalb meiner FragmentActivity verwendet, was wegen I8N nützlich ist.

1
Stephan Brunker

Ich lade Shader für openGL ES von der statischen Funktion.

Denken Sie daran, dass Sie für Ihren Datei- und Verzeichnisnamen Kleinbuchstaben verwenden müssen, da sonst die Operation fehlschlägt

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() : "";
    }

    ...

}
0
user2174870

Ich mag Abkürzungen.

Ich benutze App.getRes() anstelle von App.getContext().getResources() (wie @Cristian geantwortet hat)

Was? Es ist sehr einfach, überall in Ihrer App zu verwenden!

Hier ist eine unique-Lösung, mit der Sie von überall auf Ressourcen wie Util class zugreifen können.

(1) Erstellen oder bearbeiten Sie Ihre Application-Klasse.

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) Fügen Sie Ihrem manifest.xml<application-Tag ein Namensfeld hinzu. (oder überspringen, wenn schon dort)

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

Jetzt bist du gut zu gehen. Verwenden Sie App.getRes().getString(R.string.some_id) überall in der App.

0
Khemraj
public Static Resources mResources;

 @Override
     public void onCreate()
     {
           mResources = getResources();
     }
0
Makvin

Ich denke, es ist mehr möglich ... Aber manchmal benutze ich diese Lösung. (voll 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();
0
user2684935

In Ihrer Klasse, in der Sie die Funktion static implementieren, können Sie eine private\public - Methode aus dieser Klasse aufrufen. Die private\public-Methode kann auf die getResources zugreifen.

zum Beispiel:

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));
   }
}

und aus einer anderen Klasse\Aktivität können Sie anrufen: 

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

Ich benutze API Level 27 und habe nach rund zwei Tagen Schwierigkeiten gefunden. Wenn Sie eine XML-Datei aus einer Klasse lesen möchten, die nicht von Activity oder Application abgeleitet ist, gehen Sie wie folgt vor. 

  1. Legen Sie die Datei testdata.xml im Assets-Verzeichnis ab.

  2. Schreiben Sie den folgenden Code, um das testdata-Dokument zu analysieren.

        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);
    
0
Jnana

wenn Sie einen Kontext haben, meine ich innen; 

public void onReceive(Context context, Intent intent){

}

sie können diesen Code verwenden, um Ressourcen zu erhalten:

context.getResources().getString(R.string.app_name);
0
eren130