Jak Mogę uzyskać zawartość zasobu ze statycznego kontekstu?
Chcę odczytać ciągi znaków z pliku xml
, zanim zrobię coś innego, jak setText
na widgetach, więc jak Mogę to zrobić bez obiektu activity do wywołania getResources()
?
14 answers
- Utwórz podklasę
Application
, na przykładpublic class App extends Application {
- ustaw atrybut
android:name
twojego znacznika<application>
wAndroidManifest.xml
, aby wskazywał na nową klasę, np.android:name=".App"
- W metodzie
onCreate()
instancji aplikacji zapisz swój kontekst (np.this
) do statycznego pola o nazwiemContext
i utwórz statyczną metodę, która zwróci To pole, np.getContext()
:
Tak powinno wyglądać:
public class App extends Application{
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext(){
return mContext;
}
}
Teraz możesz użyć: App.getContext()
Kiedy chcesz uzyskać kontekst, a następnie getResources()
(lub App.getContext().getResources()
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-14 15:44:59
Tylko dla zasobów systemowych!
Użycie
Resources.getSystem().getString(android.R.string.cancel)
Możesz ich używać wszędzie w swojej aplikacji, nawet w deklaracjach stałych statycznych!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-11 03:09:52
Moim rozwiązaniem Kotlin jest użycie statycznego kontekstu aplikacji:
class App : Application() {
companion object {
lateinit var instance: App private set
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
I klasa Strings, której używam wszędzie:
object Strings {
fun get(@StringRes stringRes: Int, vararg formatArgs: Any = emptyArray()): String {
return App.instance.getString(stringRes, *formatArgs)
}
}
Więc możesz mieć czysty sposób uzyskiwania ciągów zasobów
Strings.get(R.string.some_string)
Strings.get(R.string.some_string_with_arguments, "Some argument")
Proszę nie kasować tej odpowiedzi, pozwól mi zachować jedną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-30 14:36:23
Jest też inna możliwość. Wczytuję shadery OpenGl z takich zasobów:
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);
}
Jak widzisz, możesz uzyskać dostęp do dowolnego zasobu w path /res/...
Zmień aClass
na swoją klasę. To również jak Ładuję zasoby w testach (androidTests)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-12 09:07:17
Skrót
Używam App.getRes()
zamiast App.getContext().getResources()
(Jak odpowiedział @ Cristian)
Jest bardzo prosty w użyciu w dowolnym miejscu kodu!
Oto unikalne rozwiązanie , dzięki któremu możesz uzyskać dostęp do zasobów z dowolnego miejsca, takiego jak Util class
.
(1) Utwórz lub Edytuj klasę 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 getRes() {
return res;
}
}
(2) Dodaj pole nazwa do swojego manifest.xml
<application
tag. (lub pomiń to, jeśli już tam jest)
<application
android:name=".App"
...
>
...
</application>
Teraz możesz iść.
Użyj App.getRes().getString(R.string.some_id)
w dowolnym miejscu kodu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-04 09:29:00
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;
}
}
Zainicjalizuj Singleton w swojej podklasie 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);
}
}
Jeśli Im się nie myli, to daje Ci hook do applicationContext wszędzie, wywołaj go za pomocą ApplicationContextSingleton.getInstance.getApplicationContext();
Nie powinieneś tego usuwać w dowolnym momencie, ponieważ po zamknięciu aplikacji i tak to idzie z nią.
Pamiętaj, aby zaktualizować AndroidManifest.xml
, aby użyć tej Application
podklasy:
<?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"
>
Teraz powinieneś móc używać ApplicationContextSingleton.getInstance ().getApplicationContext ().getResources () from wszędzie, również w niewielu miejscach, w których podklasy aplikacji nie mogą.
Proszę dać mi znać, jeśli zobaczysz coś złego tutaj, dziękuję. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 12:30:50
Inne rozwiązanie:
Jeśli masz statyczną podklasę w niestatycznej zewnętrznej klasie, możesz uzyskać dostęp do zasobów z podklasy za pomocą statycznych zmiennych w zewnętrznej klasie, które inicjalizujesz podczas tworzenia zewnętrznej klasy. Jak
public class Outerclass {
static String resource1
public onCreate() {
resource1 = getString(R.string.text);
}
public static class Innerclass {
public StringGetter (int num) {
return resource1;
}
}
}
Użyłem go do funkcji getPageTitle(int position) statycznego Fragmentpageradaptera w moim FragmentActivity, co jest przydatne ze względu na I8N.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 23:58:24
Myślę, że jest więcej możliwości. Ale czasami korzystam z tego rozwiązania. "full 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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-13 19:23:04
Ładuję shader dla openGL ES z funkcji statycznej.
Pamiętaj, że musisz użyć małych liter dla nazwy pliku i katalogu, w przeciwnym razie operacja nie powiedzie się
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() : "";
}
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-31 15:40:50
Używam API poziomu 27 i znalazłem najlepsze rozwiązanie po około dwóch dniach zmagań. Jeśli chcesz odczytać plik xml z klasy, która nie pochodzi z aktywności lub aplikacji, wykonaj następujące czynności.
Umieść dane testowe.plik xml w katalogu zasobów.
-
Napisz poniższy kod, aby uzyskać przetworzenie dokumentu 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-12 23:54:21
Uzyskanie obrazu resouse jako InputStream bez kontekstu:
Class<? extends MyClass> aClass = MyClass.class;
URL r = aClass.getResource("/res/raw/test.png");
URLConnection urlConnection = r.openConnection();
return new BufferedInputStream(urlConnection.getInputStream());
Jeśli potrzebujesz drzewa derektory dla swoich plików, będzie ono również działać (zasoby obsługują sub-dirs):
URL r = aClass.getResource("/assets/images/base/2.png");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-12 23:40:38
W twojej klasie, gdzie implementujesz funkcję static , możesz wywołać metodę private\public z tej klasy. Metoda private \ public może uzyskać dostęp do getResources .
Na przykład:
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));
}
}
I z innej klasy \ activity można wywołać:
Text.setColor('some EditText you initialized');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-13 08:55:48
Jeśli masz kontekst, mam na myśli wewnątrz;
public void onReceive(Context context, Intent intent){
}
Możesz użyć tego kodu, aby uzyskać zasoby:
context.getResources().getString(R.string.app_name);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 19:45:28
public Static Resources mResources;
@Override
public void onCreate()
{
mResources = getResources();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-26 07:21:18