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

Java 如何从静态上下文中获取资源内容?,java,android,static,constants,android-resources,Java,Android,Static,Constants,Android Resources,我想先从xml文件中读取字符串,然后再在小部件上执行类似setText的其他操作,因此,如果没有要调用getResources()的活动对象,我怎么能做到这一点呢 创建一个子类,例如公共类应用程序扩展应用程序{ 在AndroidManifest.xml中设置android:name标记的属性以指向新类,例如android:name=“.App” 在应用程序实例的onCreate()方法中,将上下文(例如this)保存到名为mContext的静态字段中,并创建一个返回此字段的静态方法,例如getC

我想先从
xml
文件中读取字符串,然后再在小部件上执行类似
setText
的其他操作,因此,如果没有要调用
getResources()
的活动对象,我怎么能做到这一点呢

  • 创建一个子类,例如<代码>公共类应用程序扩展应用程序{
  • AndroidManifest.xml
    中设置
    android:name
    标记的
    属性以指向新类,例如
    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()
    )。

    仅用于系统资源!

    使用


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

    我认为,有更多的方法是可能的。 但有时,我会使用此解决方案。(完整全局):

    导入android.content.Context;
    进口,;
    公共类XmlVar{
    私有XmlVar(){
    }
    私有静态字符串写入成功;
    公共静态字符串写入成功(){
    返回-写入-成功;
    }
    公共静态void Init(上下文c){
    _write_success=c.getResources().getString(R.string.write_success);
    }
    }
    //创建活动后:
    cont=this.getApplicationContext();
    XmlVar.Init(续);
    //到处都可以使用
    XmlVar.write_success();
    
    在您的类中,在您实现静态功能的地方,您可以从此类调用私有\公共方法。私有\公共方法可以访问获取资源

    例如:

    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));
       }
    }
    
    从其他类\活动,您可以调用:

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

    如果你有背景,我指的是内在

    public void onReceive(Context context, Intent intent){
    
    }
    
    您可以使用此代码获取资源:

    context.getResources().getString(R.string.app_name);
    
    单身人士:

    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;
        }
    
    }
    
    应用程序
    子类中初始化单例:

    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);
        }
    }
    
    <?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"
        >
    
    如果我没记错的话,这会给你一个到applicationContext的钩子,用
    ApplicationContextSingleton.getInstance.getApplicationContext();
    您不需要在任何时候清除它,因为当应用程序关闭时,无论如何都会随之关闭

    请记住更新
    AndroidManifest.xml
    以使用此
    应用程序
    子类:

    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);
        }
    }
    
    <?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"
        >
    
    
    另一个解决方案:

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

    public class Outerclass {
    
        static String resource1
    
        public onCreate() {
            resource1 = getString(R.string.text);
        }
    
        public static class Innerclass {
    
            public StringGetter (int num) {
                return resource1; 
            }
        }
    }
    

    我在FragmentActivity中使用它作为静态FragmentPagerAdapter的getPageTitle(int position)函数,这是因为I8N很有用。

    还有另一种可能性。我从以下资源加载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);
    }
    
    静态私有字符串vertexShaderCode;
    静态私有字符串片段ShaderCode;
    静止的{
    vertexShaderCode=readResourceAsString(“/res/raw/vertex_shader.glsl”);
    fragmentShaderCode=readResourceAsString(“/res/raw/fragment_shader.glsl”);
    }
    私有静态字符串readResourceAsString(字符串路径){
    异常内部异常;
    类快捷方式
    我使用
    App.getRes()
    而不是
    App.getContext().getResources()
    (如@Cristian所回答)

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

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

    (1) 创建或编辑
    应用程序

    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) 将名称字段添加到您的
    manifest.xml
    我从静态函数加载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() : "";
        }
    
        ...
    
    }
    

    我使用的是API级别27,经过大约两天的努力,我找到了一个最好的解决方案

  • 将testdata.xml文件放在assets目录中

  • 编写以下代码以解析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);
    

  • 我的Kotlin解决方案是使用静态应用程序上下文:

    class App : Application() {
        companion object {
            lateinit var instance: App private set
        }
    
        override fun onCreate() {
            super.onCreate()
            instance = this
        }
    }
    
    还有字符串类,我在任何地方都使用它:

    object Strings {
        fun get(@StringRes stringRes: Int, vararg formatArgs: Any = emptyArray()): String {
            return App.instance.getString(stringRes, *formatArgs)
        }
    }
    
    因此,您可以使用一种干净的方法获取资源字符串

    Strings.get(R.string.some_string)
    Strings.get(R.string.some_string_with_arguments, "Some argument")
    

    请不要删除此答案,让我保留一个。

    将图像资源作为无上下文的InputStream获取:

    Class<? extends MyClass> aClass = MyClass.class;
    URL r = aClass.getResource("/res/raw/test.png");
    URLConnection urlConnection = r.openConnection();
    return new BufferedInputStream(urlConnection.getInputStream());
    

    这很酷。我通常不会被冒犯…只是当有人使用大写字母:P只是开玩笑。好吧,你的标准适用于一些资源,如字符串和可绘图…然而,正如文档所说,它不适用于方向度量等。而且,最重要的是,这不允许你获得一个全局上下文有时对可能需要它的事情很有用(举一个
    Toast
    例如,获取
    SharedReference
    例如,打开一个数据库,就像我的拉丁语老师说的:等等)。你甚至不能通过它赢得全世界的和平:-)。但它有助于解决这里的问题。我并不是说它解决了所有的任务,只是它几乎解决了应用程序中的每个地方的任务。我搜索了10个月这样的解决方案-我一直在使用Android。现在我找到了。你在这里必须小心。不要这样做尝试使用此方法查找您的应用程序资源。请阅读详细说明:返回一个全局共享资源对象,该对象仅提供对系统资源(无应用程序资源)的访问权限,并且未针对当前屏幕进行配置(不能使用维度单位,不会根据
    Strings.get(R.string.some_string)
    Strings.get(R.string.some_string_with_arguments, "Some argument")
    
    Class<? extends MyClass> aClass = MyClass.class;
    URL r = aClass.getResource("/res/raw/test.png");
    URLConnection urlConnection = r.openConnection();
    return new BufferedInputStream(urlConnection.getInputStream());
    
    URL r = aClass.getResource("/assets/images/base/2.png");