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

问题描述 投票:152回答:12

在我做小部件上的xml之类的任何事情之前,我想从setText文件中读取字符串,那么如果没有活动对象来调用getResources(),我怎么能这样做呢?

java android static const android-resources
12个回答
360
投票
  1. 创建Application的子类,例如public class App extends Application {
  2. android:name中设置<application>标签的AndroidManifest.xml属性以指向新的类,例如android:name=".App"
  3. 在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())。


0
投票
public Static Resources mResources;

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

0
投票

我正在使用API​​级别27,并在经过两天的努力后找到了最佳解决方案。如果要从不从“活动”或“应用程序”派生的类中读取xml文件,请执行以下操作。

  1. 将testdata.xml文件放在assets目录中。
  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);

-1
投票

如果你有一个背景,我的意思是在里面;

public void onReceive(Context context, Intent intent){

}

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

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

98
投票

使用

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

}

Application子类中初始化Singleton:

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

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


3
投票

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


2
投票

另一种方案:

如果在非静态外部类中有静态子类,则可以通过外部类中的静态变量从子类中访问资源,外部类在创建外部类时初始化。喜欢

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很有用。


2
投票

Shortcut

我使用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
        android:name=".App"
        ...
        >
        ...
    </application>

现在你很高兴。

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


0
投票

我想,更多的方法是可能的。但有时,我使用这个解决方案。 (全球):

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

0
投票

在您的类中,您实现静态函数,您可以从此类调用private \ public方法。 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));
   }
}

从其他类\活动中,您可以致电:

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

0
投票

我从静态函数加载了用于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() : "";
    }

    ...

}
© www.soinside.com 2019 - 2024. All rights reserved.