Как я могу получить содержимое ресурса из статического контекста?

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

Ответ 1

  • Создайте подкласс Application, например public class App extends Application {
  • Установите атрибут android:name тэга <application> в AndroidManifest.xml, чтобы указать на ваш новый класс, например. android:name=".App"
  • В методе 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()).

Ответ 2

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

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

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

Ответ 3

Синглтон:

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

}

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

Если я не ошибаюсь, это дает вам доступ к applicationContext везде, назовите его 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() из любого места, а также очень мало мест, где подклассы приложений не могут.

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

Ответ 4

Есть и другая возможность. Я загружаю шейдеры 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)

Ответ 5

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

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

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.

Ответ 6

кратчайший путь

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

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

Итак, вот уникальное решение, с помощью которого вы можете получить доступ к ресурсам из любого места, например, 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. (или пропустите это, если уже есть)

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

Теперь вы готовы идти.

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

Ответ 7

Думаю, больше возможностей. Но иногда я использую это решение. (полный глобальный):

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

Ответ 8

В вашем классе, где вы реализуете функцию static, вы можете вызвать метод private\public этого класса. Частный\открытый метод может получить доступ к getResources.

, например:

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

и из другого класса \activity, вы можете вызвать:

Text.setColor('some EditText you initialized');

Ответ 9

Я загружаю шейдер для 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() : "";
    }

    ...

}

Ответ 10

public Static Resources mResources;

 @Override
     public void onCreate()
     {
           mResources = getResources();
     }

Ответ 11

Я использую 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);
    

Ответ 12

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

public void onReceive(Context context, Intent intent){

}

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

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