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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4391720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 16:54:25  来源:igfitidea点击:

How can I get a resource content from a static context?

javaandroidstaticconstandroid-resources

提问by lost baby

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

我想在对小部件xml执行其他任何操作之前从文件中读取字符串setText,那么如果没有要调用的活动对象,我该怎么做getResources()呢?

采纳答案by Cristian

  1. Create a subclass of Application, for instance public class App extends Application {
  2. Set the android:nameattribute of your <application>tag in the AndroidManifest.xmlto point to your new class, e.g. android:name=".App"
  3. In the onCreate()method of your app instance, save your context (e.g. this) to a static field named mContextand create a static method that returns this field, e.g. getContext():
  1. 创建一个子类Application,例如public class App extends Application {
  2. 将标签的android:name属性设置为指向您的新类,例如<application>AndroidManifest.xmlandroid:name=".App"
  3. 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())。

回答by Gangnus

For system resources only!

仅适用于系统资源!

Use

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

You can use them everywhere in your application, even in static constants declarations!

您可以在应用程序的任何地方使用它们,甚至在静态常量声明中!

回答by user2684935

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

回答by Maor Cohen

In your class, where you implement the staticfunction, you can call a private\publicmethod 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');

回答by eren130

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

回答by Versa

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 Applicationsubclass:

在您的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);
    }
}

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();你不应该在任何时候清除它,因为当应用程序关闭时,它无论如何都会发生。

Remember to update AndroidManifest.xmlto use this Applicationsubclass:

请记住更新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"
    >

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() ,还有应用程序子类不能使用的极少数地方。

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

如果您在这里看到任何错误,请告诉我,谢谢。:)

回答by Stephan Brunker

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.

我将它用于我的 FragmentActivity 中静态 FragmentPagerAdapter 的 getPageTitle(int position) 函数,由于 I8N,它很有用。

回答by Gregory Stein

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 aClassto your class. This also how I load resources in tests (androidTests)

如您所见,您可以访问路径/res/...Change 中的任何资源aClass到您的班级。这也是我在测试中加载资源的方式(androidTests)

回答by Khemraj

Shortcut

捷径

I use App.getRes()instead of App.getContext().getResources()(as @Cristian answered)

我用App.getRes()而不是App.getContext().getResources()(正如@Cristian 回答的那样)

It is very simple to use anywhere in your code!

在代码中的任何地方使用都非常简单!

So here is a unique solutionby which you can access resources from anywhere like Util class.

因此,这是一个独特的解决方案,您可以通过它从任何地方访问资源,例如Util class.

(1) Create or Edit your Applicationclass.

(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) Add name field to your manifest.xml<applicationtag. (or Skip this if already there)

(2) 将名称字段添加到您的manifest.xml<application标签中。(或如果已经存在则跳过)

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

Now you are good to go.

现在你可以走了。

Use App.getRes().getString(R.string.some_id)anywhere in code.

App.getRes().getString(R.string.some_id)在代码中的任何地方使用。

回答by user2174870

I load shader for openGL ES from static function.

我从静态函数加载 openGL ES 的着色器。

Remember you must use lower case for your file and directory name, or else the operation will be failed

请记住,您的文件和目录名必须使用小写,否则操作将失败

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() : "";
    }

    ...

}