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

时间:2010-12-08 20:03:08

标签: java android static const android-resources

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

15 个答案:

答案 0 :(得分:358)

  1. 创建Application的子类,例如public class App extends Application {
  2. android:name<application>标记的AndroidManifest.xml属性设置为指向新类,例如android:name=".App"
  3. 在您的应用实例的onCreate()方法中,将您的上下文(例如this)保存到名为mContext的静态字段,并创建一个返回此字段的静态方法,例如getContext()
  4. 这应该是它的样子:

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

答案 1 :(得分:98)

使用

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

您可以在应用程序的任何地方使用它们,即使在静态常量声明中也是如此! 但仅限系统资源!

答案 2 :(得分: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;
    }

}

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 :(得分: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)

答案 4 :(得分: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很有用。

答案 5 :(得分:1)

快捷方式

我使用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>

现在你很好。

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

答案 6 :(得分:1)

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

class App : Application() {
    companion object {
        lateinit var instance: App private set
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}

我在各处使用的Strings类:

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

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

答案 7 :(得分: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();

答案 8 :(得分: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');

答案 9 :(得分: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() : "";
    }

    ...

}

答案 10 :(得分:0)

public Static Resources mResources;

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

答案 11 :(得分:0)

我正在使用API​​级别27,并且在奋斗了大约两天后找到了一个最佳解决方案。如果要从不是从Activity或Application派生的类中读取xml文件,请执行以下操作。

  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 :(得分:0)

在没有上下文的情况下将图像作为输入流获取

CREATE TABLE `students` (
  `FirstName` varchar(25),
  `MiddleName` varchar(25),
  `Lastname` varchar(25),
 `StudentNumber` int(6)
);
INSERT INTO students (FirstName,MiddleName,Lastname,StudentNumber) VALUES ('Steve', 'Glenn', 'Bronze', 2591);
INSERT INTO students (FirstName,MiddleName,Lastname,StudentNumber) VALUES ('James', 'Paul', 'Smith', 2592);
INSERT INTO students (FirstName,MiddleName,Lastname,StudentNumber) VALUES ('Al', 'Matt', 'Sutter', 2593);


CREATE TABLE `attendance` (
  `Activity_Id` int(8) NOT NULL,
  `StudentNumber` int(6) DEFAULT NULL,
  `Activity_Location` varchar(17) DEFAULT NULL,
  `Entry_Date` datetime DEFAULT NULL,
  `Offline_Total_Hours` varchar(5) DEFAULT NULL,
  `Online_Total_Hours` varchar(6) DEFAULT NULL,
  `Record_Status` varchar(9) DEFAULT NULL,
  `Student_Email` varchar(24) DEFAULT NULL,
  `Attendance_Activity` varchar(100) DEFAULT NULL,
  `Attendance_Type` varchar(19) DEFAULT NULL,
  `Time_End` datetime DEFAULT NULL,
  `Time_End_Online` varchar(19) DEFAULT NULL,
  `Time_Start` datetime DEFAULT NULL,
  `Time_Start_Online` varchar(19) DEFAULT NULL,
  `TotalHoursDay` decimal(3,2) DEFAULT NULL,
  `Staff_id` int(4) DEFAULT NULL,
  `Override_Reason` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `attendance`
--

INSERT INTO `attendance` (`Activity_Id`, `StudentNumber`, `Activity_Location`, `Entry_Date`, `Offline_Total_Hours`, `Online_Total_Hours`, `Record_Status`, `Student_Email`, `Attendance_Activity`, `Attendance_Type`, `Time_End`, `Time_End_Online`, `Time_Start`, `Time_Start_Online`, `TotalHoursDay`, `Staff_id`, `Override_Reason`) VALUES
(110, 2591, 'Lab', '2019-09-09 00:10:38', NULL, NULL, NULL, NULL, 'Online', '1', '2019-09-09 23:57:00', NULL, '2019-09-09 22:27:00', NULL, NULL, 0, ''),
(113, 2591, 'Lab', '2019-09-09 06:34:08', NULL, NULL, NULL, NULL, 'Online', '1', '2019-09-09 06:33:00', NULL, '2019-09-09 00:34:00', NULL, NULL, 0, ''),
(114, 2592, 'Lab', '2019-09-09 07:22:20', NULL, NULL, NULL, NULL, 'Online', '1', '2019-09-09 08:21:00', NULL, '2019-09-09 07:21:00', NULL, NULL, 0, ''),
(116, 2592, 'Lab', '2019-09-09 07:44:06', NULL, NULL, NULL, NULL, 'Online', '1', '2019-09-09 12:30:00', NULL, '2019-09-09 07:00:00', NULL, NULL, 0, '');


如果您需要文件的目录树,它也将起作用(资产支持子目录):

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

答案 13 :(得分:0)

为什么不尝试

Resources.getSystem().getString(R.string.foo);

答案 14 :(得分:-1)

如果你有上下文,我的意思是在里面;

vcombine_u8

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

public void onReceive(Context context, Intent intent){

}