Как я могу получить контент ресурса из статического контекста? - PullRequest
156 голосов
/ 08 декабря 2010

Я хочу прочитать строки из файла xml, прежде чем я сделаю что-то еще, например, setText для виджетов, так как я могу сделать это без объекта активности для вызова getResources()?

Ответы [ 12 ]

360 голосов
/ 08 декабря 2010
  1. Создать подкласс Application, например public class App extends Application {
  2. Установите атрибут android:name вашего тега <application> в AndroidManifest.xml, чтобы указатьв свой новый класс, например android:name=".App"
  3. В методе onCreate() экземпляра приложения сохраните свой контекст (например, this) в статическом поле с именем mContext и создайте статический метод, который возвращаетэто поле, например getContext():

Вот как это должно выглядеть:

public class App extends Application{

    private static Context mContext;

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

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

Теперь вы можете использовать: App.getContext() всякий раз, когда вы хотите получить контекст, изатем getResources() (или App.getContext().getResources()).

98 голосов
/ 07 января 2012

Использование

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

Вы можете использовать их повсюду в приложении, даже в объявлениях статических констант!Но только для системных ресурсов!

3 голосов
/ 12 февраля 2017

Есть и другая возможность. Я загружаю шейдеры OpenGl из таких ресурсов:

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

Как видите, вы можете получить доступ к любому ресурсу по пути /res/... Измените aClass на свой класс. Это также, как я загружаю ресурсы в тестах (androidTests)

3 голосов
/ 25 сентября 2015

Синглтон:

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

}

Инициализируйте синглтон в вашем подклассе 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);
    }
}

Если я не ошибаюсь, это дает вам повод для приложенияContext везде,Назовите его с ApplicationContextSingleton.getInstance.getApplicationContext(); Вам не нужно очищать это в любой момент, так как когда приложение закрывается, это все равно происходит с ним.

Не забудьте обновить AndroidManifest.xml, чтобы использовать этот 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"
    >

Теперь вы должны иметь возможность использовать ApplicationContextSingleton.getInstance (). GetApplicationContext (). GetResources () из любого места, а также из очень немногих мест, где подклассы приложения не могут.

Пожалуйста,дайте мне знать, если вы видите здесь что-то не так, спасибо.:)

2 голосов
/ 11 июля 2018

Ярлык

Я использую App.getRes() вместо App.getContext().getResources() (как ответил @Cristian)

Очень просто использовать в любом месте вашего кода!

Итак, вот уникальное решение 1012 *, с помощью которого вы можете получить доступ к ресурсам из любого места, например Util class.

(1) Создать или отредактировать свой 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) Добавьте поле имени в тег manifest.xml <application.(или пропустите это, если уже есть)

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

Теперь все готово.

Используйте App.getRes().getString(R.string.some_id) в любом месте кода.

2 голосов
/ 22 октября 2016

Другое решение:

Если у вас есть статический подкласс в нестатическом внешнем классе, вы можете получить доступ к ресурсам из этого подкласса через статические переменные во внешнем классе, которые вы инициализируете при созданиивнешний класс.Как и

public class Outerclass {

    static String resource1

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

    public static class Innerclass {

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

Я использовал его для функции getPageTitle (int position) статического FragmentPagerAdapter в рамках моей FragmentActivity, что полезно из-за I8N.

0 голосов
/ 13 февраля 2019

Я использую API уровня 27 и нашел лучшее решение после двух дней борьбы.Если вы хотите прочитать XML-файл из класса, который не является производным от Activity или Application, сделайте следующее.

  1. Поместите файл testdata.xml в каталог ресурсов.

  2. Введите следующий код для анализа документа 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 голосов
/ 26 сентября 2018
public Static Resources mResources;

 @Override
     public void onCreate()
     {
           mResources = getResources();
     }
0 голосов
/ 31 августа 2018

Я загружаю шейдер для openGL ES из статической функции.

Помните, что вы должны использовать нижний регистр для имени файла и каталога, иначе операция будет неудачной

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 голосов
/ 26 мая 2015

если у вас есть контекст, я имею в виду внутри;

public void onReceive(Context context, Intent intent){

}

Вы можете использовать этот код для получения ресурсов:

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