Je veux lire les chaînes d'un fichier xml
avant de faire autre chose que setText
sur des widgets. Comment puis-je le faire sans objet d'activité sur lequel appeler getResources()
?
Application
, par exemple public class App extends Application {
Android:name
de votre balise <application>
dans AndroidManifest.xml
pour qu'il pointe vers votre nouvelle classe, par exemple. Android:name=".App"
onCreate()
de votre instance d'application, enregistrez votre contexte (par exemple, this
) dans un champ statique nommé mContext
et créez une méthode statique qui renvoie ce champ, par exemple. getContext()
:Voici à quoi cela devrait ressembler:
public class App extends Application{
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext(){
return mContext;
}
}
Vous pouvez maintenant utiliser: App.getContext()
chaque fois que vous souhaitez obtenir un contexte, puis getResources()
(ou App.getContext().getResources()
).
Utilisation
Resources.getSystem().getString(Android.R.string.cancel)
Vous pouvez les utiliser partout dans votre application, même dans les déclarations de constantes statiques! Mais uniquement pour les ressources système!
Il y a aussi une autre possibilité. Je charge les shaders OpenGl à partir de ressources comme ceci:
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);
}
Comme vous pouvez le constater, vous pouvez accéder à n’importe quelle ressource du chemin /res/...
Modifiez aClass
en votre classe. Cela aussi comment je charge les ressources dans les tests (androidTests)
Le 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;
}
}
Initialisez le singleton dans votre sous-classe Application
:
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 je ne me trompe pas, cela vous accroche partout dans applicationContext, appelez-le avec ApplicationContextSingleton.getInstance.getApplicationContext();
Vous ne devriez pas avoir à effacer cela à aucun moment.
N'oubliez pas de mettre à jour AndroidManifest.xml
pour utiliser cette sous-classe Application
:
<?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"
>
Vous devriez maintenant pouvoir utiliser ApplicationContextSingleton.getInstance (). GetApplicationContext (). GetResources () de n'importe où, ainsi que des rares endroits où les sous-classes d'application ne peuvent pas.
S'il vous plaît laissez-moi savoir si vous voyez quelque chose de mal, merci. :)
Une autre solution:
Si vous avez une sous-classe statique dans une classe externe non statique, vous pouvez accéder aux ressources à partir de la sous-classe via des variables statiques de la classe externe, que vous initialisez à la création de la classe externe. Comme
public class Outerclass {
static String resource1
public onCreate() {
resource1 = getString(R.string.text);
}
public static class Innerclass {
public StringGetter (int num) {
return resource1;
}
}
}
Je l'ai utilisé pour la fonction getPageTitle (int position), fonction de FragmentPagerAdapter statique dans FragmentActivity, ce qui est utile en raison de I8N.
Je charge shader pour OpenGL ES depuis une fonction statique.
N'oubliez pas que vous devez utiliser des minuscules pour votre nom de fichier et de répertoire, sinon l'opération échouera
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() : "";
}
...
}
J'aime les raccourcis.
J'utilise App.getRes()
au lieu de App.getContext().getResources()
(comme @Cristian a répondu)
Quoi? Il est très simple d'utiliser n'importe où dans votre application!
Voici donc une solution unique grâce à laquelle vous pouvez accéder à des ressources n’importe où, comme Util class
.
(1) Créez ou éditez votre classe Application
.
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) Ajoutez un champ de nom à votre balise manifest.xml
<application
. (ou ignorer si c'est déjà fait)
<application
Android:name=".App"
...
>
...
</application>
Maintenant vous êtes prêt à partir. Utilisez App.getRes().getString(R.string.some_id)
n'importe où dans l'application.
public Static Resources mResources;
@Override
public void onCreate()
{
mResources = getResources();
}
Je pense qu’il ya plus de chemin possible… .. Mais parfois, j’utilise cette solution. (global complet):
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();
Dans votre classe, où vous implémentez la fonction static , vous pouvez appeler une méthode private\public de cette classe. La méthode private\public peut accéder à getResources .
par exemple:
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));
}
}
et depuis une autre classe\activité, vous pouvez appeler:
Text.setColor('some EditText you initialized');
J'utilise le niveau 27 de l'API et j'ai trouvé la meilleure solution après deux jours de difficultés. Si vous souhaitez lire un fichier XML à partir d'une classe qui ne dérive pas d'Activity ou Application, procédez comme suit.
Placez le fichier testdata.xml dans le répertoire assets.
Écrivez le code suivant pour obtenir le document testdata analysé.
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);
si vous avez un contexte, je veux dire à l'intérieur;
public void onReceive(Context context, Intent intent){
}
vous pouvez utiliser ce code pour obtenir des ressources:
context.getResources().getString(R.string.app_name);