Je veux lire les chaînes d'un xml
fichier avant de faire quoi que ce soit d'autre, comme setText
sur les widgets, alors comment puis-je faire cela sans objet d'activité à appeler getResources()
?
Je veux lire les chaînes d'un xml
fichier avant de faire quoi que ce soit d'autre, comme setText
sur les widgets, alors comment puis-je faire cela sans objet d'activité à appeler getResources()
?
Réponses:
Application
, par exemplepublic class App extends Application {
android:name
attribut de votre <application>
balise dans AndroidManifest.xml
pour pointer vers votre nouvelle classe, par exempleandroid:name=".App"
onCreate()
méthode 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 désormais utiliser: à App.getContext()
chaque fois que vous souhaitez obtenir un contexte, puis getResources()
(ou App.getContext().getResources()
).
Pour les ressources système uniquement!
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!
Toast
par exemple, lever une SharedPreference
instance, ouvrir une base de données, comme le dit mon professeur de langue latine: et cetera ).
Ma solution Kotlin consiste à utiliser un contexte d'application statique:
class App : Application() {
companion object {
lateinit var instance: App private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
Et la classe Strings, que j'utilise partout:
object Strings {
fun get(@StringRes stringRes: Int, vararg formatArgs: Any = emptyArray()): String {
return App.instance.getString(stringRes, *formatArgs)
}
}
Ainsi, vous pouvez avoir un moyen propre d'obtenir des chaînes de ressources
Strings.get(R.string.some_string)
Strings.get(R.string.some_string_with_arguments, "Some argument")
Veuillez ne pas supprimer cette réponse, laissez-moi en garder une.
Strings
été utile.
Il y a aussi une autre possibilité. Je charge des shaders OpenGl à partir de ressources comme celle-ci:
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 voir, vous pouvez accéder à n'importe quelle ressource dans le chemin /res/...
Change aClass
vers votre classe. C'est aussi comment je charge des 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 Application
sous-classe:
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 donne un accès à applicationContext partout, appelez-le avec ApplicationContextSingleton.getInstance.getApplicationContext();
Vous ne devriez pas avoir besoin de l'effacer à aucun moment, car lorsque l'application se ferme, cela va avec de toute façon.
N'oubliez pas de mettre à jour AndroidManifest.xml
pour utiliser cette Application
sous - classe:
<?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 les très 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 ici, merci. :)
Une autre solution:
Si vous avez une sous-classe statique dans une classe externe non statique, vous pouvez accéder aux ressources depuis la sous-classe via des variables statiques dans la classe externe, que vous initialisez lors de 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 (position int) du FragmentPagerAdapter statique dans mon FragmentActivity, ce qui est utile en raison de I8N.
J'utilise à la App.getRes()
place de App.getContext().getResources()
(comme @Cristian a répondu)
Il est très simple à utiliser n'importe où dans votre code!
Voici donc une solution unique par laquelle vous pouvez accéder aux ressources de n'importe où Util class
.
(1) Créez ou modifiez votre Application
classe.
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 manifest.xml
<application
balise. (ou sauter ceci si déjà là)
<application
android:name=".App"
...
>
...
</application>
Maintenant, vous êtes prêt à partir.
App.getRes().getString(R.string.some_id)
n'importe où dans le code.Je pense que plus de chemin est 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();
Je charge le shader pour openGL ES à partir de la fonction statique.
N'oubliez pas que vous devez utiliser des minuscules pour le nom de votre fichier et de votre 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() : "";
}
...
}
public Static Resources mResources;
@Override
public void onCreate()
{
mResources = getResources();
}
J'utilise le niveau d'API 27 et j'ai trouvé la meilleure solution après avoir lutté pendant environ deux jours. Si vous souhaitez lire un fichier xml d'une classe qui ne dérive pas d'Activité ou d'Application, procédez comme suit.
Placez le fichier testdata.xml dans le répertoire des ressources.
Écrivez le code suivant pour analyser le document testdata.
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);
Dans votre classe, où vous implémentez la fonction statique , vous pouvez appeler une méthode private \ public à partir 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');
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);