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()?

Author: Gangnus, 2010-12-08

14 answers

  1. Utwórz podklasę Application, na przykład public class App extends Application {
  2. ustaw atrybut android:name twojego znacznika <application> w AndroidManifest.xml, aby wskazywał na nową klasę, np. android:name=".App"
  3. W metodzie onCreate() instancji aplikacji zapisz swój kontekst (np. this) do statycznego pola o nazwie mContext 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()).

 381
Author: Cristian,
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!

 102
Author: Gangnus,
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ą.

 9
Author: Vitalii Malyi,
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)

 6
Author: Gregory Stein,
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.

 4
Author: Khemraj,
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ę. :)

 3
Author: Versa,
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.

 2
Author: Stephan Brunker,
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();
 0
Author: user2684935,
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() : "";
    }

    ...

}
 0
Author: user2174870,
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.

  1. Umieść dane testowe.plik xml w katalogu zasobów.

  2. 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);
    
 0
Author: Jnana,
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");
 0
Author: Yuliia Ashomok,
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');
 -1
Author: Maor Cohen,
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);
 -1
Author: Eren,
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();
     }
 -1
Author: Makvin,
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