如何从静态上下文获取资源内容?

时间:2022-03-14 10:14:38

I want to read strings from an xml file before I do much of anything else like setText on widgets, so how can I do that without an activity object to call getResources() on?

我想从xml文件中读取字符串,然后在小部件上做其他任何事情,比如setText,那么我怎么能在没有活动对象的情况下调用getResources()呢?

8 个解决方案

#1


320  

  1. Create a subclass of Application, for instance public class App extends Application {
  2. 创建应用程序的子类,例如公共类应用程序扩展应用程序{
  3. Set the android:name attribute of your <application> tag in the AndroidManifest.xml to point to your new class, e.g. android:name=".App"
  4. 在AndroidManifest中设置 标签的android:name属性。指向新类的xml,例如:android:name=".App"
  5. In the onCreate() method of your app instance, save your context (e.g. this) to a static field named mContext and create a static method that returns this field, e.g. getContext():
  6. 在应用程序实例的onCreate()方法中,将您的上下文(例如:this)保存到一个名为mContext的静态字段中,并创建一个返回该字段的静态方法,例如getContext():

This is how it should look:

它应该是这样的:

public class App extends Application{

    private static Context mContext;

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

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

Now you can use: App.getContext() whenever you want to get a context, and then getResources() (or App.getContext().getResources()).

现在您可以使用:App.getContext(),每当您想要获取上下文,然后getResources()(或App.getContext().getResources())。

#2


94  

Use

使用

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

You can use them everywhere in your application, even in static constants declarations! But for system resources only!

您可以在应用程序的任何地方使用它们,甚至在静态常量声明中也可以使用它们!但是只针对系统资源!

#3


3  

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

}

Initialize the Singleton in your Application subclass:

初始化应用程序子类中的单例:

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

If I´m not wrong, this gives you a hook to applicationContext everywhere, call it with ApplicationContextSingleton.getInstance.getApplicationContext(); You shouldn´t need to clear this at any point, as when application closes, this goes with it anyway.

如果我´没有错,这给你一个钩子applicationContext无处不在,与ApplicationContextSingleton.getInstance.getApplicationContext称之为();你应该´t需要明确这个在任何时候,当应用程序关闭,这是无论如何。

Remember to update AndroidManifest.xml to use this Application subclass:

记得更新AndroidManifest。使用此应用程序子类的xml:

<?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"
    >

Now you should be able to use ApplicationContextSingleton.getInstance().getApplicationContext().getResources() from anywhere, also the very few places where application subclasses can´t.

现在,您应该能够使用ApplicationContextSingleton.getInstance().getApplicationContext().getResources()从任何地方,也很少应用子类可以´t的地方。

Please let me know if you see anything wrong here, thank you. :)

如果您觉得这里有什么问题,请告诉我,谢谢。:)

#4


1  

Another solution:

另一个解决方案:

If you have a static subclass in a non-static outer class, you can access the resources from within the subclass via static variables in the outer class, which you initialise on creation of the outer class. Like

如果在非静态外部类中有一个静态子类,那么可以通过外部类中的静态变量从子类中访问资源,在创建外部类时初始化这些变量。就像

public class Outerclass {

    static String resource1

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

    public static class Innerclass {

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

I used it for the getPageTitle(int position) Function of the static FragmentPagerAdapter within my FragmentActivity which is useful because of I8N.

我将它用于我的FragmentPagerAdapter的getPageTitle(int position)函数,它在我的FragmentActivity中非常有用,因为I8N。

#5


1  

There is also another possibilty. I load OpenGl shaders from resources like this:

还有另一种可能性。我从资源中加载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);
}

As you can see, you can access any resource in path /res/... Change aClass to your class. This also how I load resources in tests (androidTests)

如您所见,您可以访问path /res/…把你的课改一节。这也是我在测试中加载资源的方式(androidTests)

#6


0  

I think, more way is possible. But sometimes, I using this solution. (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();

#7


0  

In your class, where you implement the static function, you can call a private\public method from this class. The private\public method can access the getResources.

在实现静态函数的类中,可以从这个类中调用private\public方法。私有的\公共方法可以访问getResources。

for example:

例如:

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

and from other class\activity, you can call:

从其他类别的\活动中,你可以调用:

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

#8


-1  

if you have a context, i mean inside;

如果你有一个背景,我是说在里面;

public void onReceive(Context context, Intent intent){

}

you can use this code to get resources:

您可以使用此代码获取资源:

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

#1


320  

  1. Create a subclass of Application, for instance public class App extends Application {
  2. 创建应用程序的子类,例如公共类应用程序扩展应用程序{
  3. Set the android:name attribute of your <application> tag in the AndroidManifest.xml to point to your new class, e.g. android:name=".App"
  4. 在AndroidManifest中设置 标签的android:name属性。指向新类的xml,例如:android:name=".App"
  5. In the onCreate() method of your app instance, save your context (e.g. this) to a static field named mContext and create a static method that returns this field, e.g. getContext():
  6. 在应用程序实例的onCreate()方法中,将您的上下文(例如:this)保存到一个名为mContext的静态字段中,并创建一个返回该字段的静态方法,例如getContext():

This is how it should look:

它应该是这样的:

public class App extends Application{

    private static Context mContext;

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

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

Now you can use: App.getContext() whenever you want to get a context, and then getResources() (or App.getContext().getResources()).

现在您可以使用:App.getContext(),每当您想要获取上下文,然后getResources()(或App.getContext().getResources())。

#2


94  

Use

使用

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

You can use them everywhere in your application, even in static constants declarations! But for system resources only!

您可以在应用程序的任何地方使用它们,甚至在静态常量声明中也可以使用它们!但是只针对系统资源!

#3


3  

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

}

Initialize the Singleton in your Application subclass:

初始化应用程序子类中的单例:

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

If I´m not wrong, this gives you a hook to applicationContext everywhere, call it with ApplicationContextSingleton.getInstance.getApplicationContext(); You shouldn´t need to clear this at any point, as when application closes, this goes with it anyway.

如果我´没有错,这给你一个钩子applicationContext无处不在,与ApplicationContextSingleton.getInstance.getApplicationContext称之为();你应该´t需要明确这个在任何时候,当应用程序关闭,这是无论如何。

Remember to update AndroidManifest.xml to use this Application subclass:

记得更新AndroidManifest。使用此应用程序子类的xml:

<?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"
    >

Now you should be able to use ApplicationContextSingleton.getInstance().getApplicationContext().getResources() from anywhere, also the very few places where application subclasses can´t.

现在,您应该能够使用ApplicationContextSingleton.getInstance().getApplicationContext().getResources()从任何地方,也很少应用子类可以´t的地方。

Please let me know if you see anything wrong here, thank you. :)

如果您觉得这里有什么问题,请告诉我,谢谢。:)

#4


1  

Another solution:

另一个解决方案:

If you have a static subclass in a non-static outer class, you can access the resources from within the subclass via static variables in the outer class, which you initialise on creation of the outer class. Like

如果在非静态外部类中有一个静态子类,那么可以通过外部类中的静态变量从子类中访问资源,在创建外部类时初始化这些变量。就像

public class Outerclass {

    static String resource1

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

    public static class Innerclass {

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

I used it for the getPageTitle(int position) Function of the static FragmentPagerAdapter within my FragmentActivity which is useful because of I8N.

我将它用于我的FragmentPagerAdapter的getPageTitle(int position)函数,它在我的FragmentActivity中非常有用,因为I8N。

#5


1  

There is also another possibilty. I load OpenGl shaders from resources like this:

还有另一种可能性。我从资源中加载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);
}

As you can see, you can access any resource in path /res/... Change aClass to your class. This also how I load resources in tests (androidTests)

如您所见,您可以访问path /res/…把你的课改一节。这也是我在测试中加载资源的方式(androidTests)

#6


0  

I think, more way is possible. But sometimes, I using this solution. (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();

#7


0  

In your class, where you implement the static function, you can call a private\public method from this class. The private\public method can access the getResources.

在实现静态函数的类中,可以从这个类中调用private\public方法。私有的\公共方法可以访问getResources。

for example:

例如:

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

and from other class\activity, you can call:

从其他类别的\活动中,你可以调用:

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

#8


-1  

if you have a context, i mean inside;

如果你有一个背景,我是说在里面;

public void onReceive(Context context, Intent intent){

}

you can use this code to get resources:

您可以使用此代码获取资源:

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