304

我发现在R.string我的代码中保留硬编码字符串非常棒,我想继续在一个实用程序类中使用它,该类与我的应用程序中的模型一起使用以生成输出。例如,在这种情况下,我正在从活动之外的模型生成一封电子邮件。

是否可以在orgetString之外使用ContextActivity?我想我可以通过当前活动,但这似乎没有必要。如果我错了,请纠正我!

编辑:我们可以在使用的情况下访问资源Context吗?

4

13 回答 13

528

是的,我们可以在不使用 `Context` 的情况下访问资源

您可以使用:

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

...在您的应用程序中的任何地方,甚至在静态常量声明中。不幸的是,它只支持系统资源

对于本地资源,请使用此解决方案。这不是微不足道的,但它确实有效。

于 2012-01-06T23:21:14.933 回答
114

不幸的是,您可以访问任何字符串资源的唯一方法是使用 a Context(即 an Activityor Service)。在这种情况下,我通常所做的只是要求调用者传入上下文。

于 2010-11-23T06:37:43.387 回答
39

MyApplication中,延伸Application

public static Resources resources;

在: MyApplication_onCreate

resources = getResources();

现在,您可以在应用程序的任何位置使用此字段。

于 2015-03-10T17:14:26.563 回答
28

##独特的方法

##App.getRes().getString(R.string.some_id)

这将在应用程序的任何地方工作。(应用程序中的 Util 类、Dialog、Fragment 或任何类

(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 getRes() {
        return res;
    }

}

(2) 将名称字段添加到您的manifest.xml <application标签。

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

现在你可以走了。在应用程序的任何地方使用App.getRes().getString(R.string.some_id)

于 2018-07-11T07:32:29.240 回答
24

顺便说一句,找不到符号错误的原因之一可能是您的 IDE 导入了 android.R;类而不是你的类。只需更改import android.R; 导入your.namespace.R;

因此,在不同的类中获得字符串可见的 2 个基本事项:

//make sure you are importing the right R class
import your.namespace.R;

//don't forget about the context
public void some_method(Context context) {
   context.getString(R.string.YOUR_STRING);
}
于 2012-05-24T06:30:21.810 回答
4

如果您有一个在活动中使用的类并且您希望访问该类中的资源,我建议您将上下文定义为类中的私有变量并在构造函数中对其进行初始化:

public class MyClass (){
    private Context context;

    public MyClass(Context context){
       this.context=context;
    }

    public testResource(){
       String s=context.getString(R.string.testString).toString();
    }
}

在你的活动中创造一个瞬间:

MyClass m=new MyClass(this);
于 2016-03-13T07:14:25.757 回答
2

Khemraj 回应的最佳方法:

应用类

class App : Application() {

    companion object {
        lateinit var instance: Application
        lateinit var resourses: Resources
    }


    // MARK: - Lifecycle

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

}

清单中的声明

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

常量类

class Localizations {

    companion object {
        val info = App.resourses.getString(R.string.info)
    }

}

使用

textView.text = Localizations.info
于 2019-02-14T08:53:05.590 回答
1

您可以在Kotlin中通过创建一个扩展 Application 的类来执行此操作,然后使用其上下文在代码中的任何位置调用资源

您的 App 类将如下所示

 class App : Application() {
    override fun onCreate() {
        super.onCreate()
        context = this
    }

    companion object {
        var context: Context? = null
            private set
    }
}

在 AndroidManifest.xml 中声明你的 Application 类(非常重要)

<application
        android:allowBackup="true"
        android:name=".App" //<--Your declaration Here
        ...>
        <activity
            android:name=".SplashActivity"  android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".MainActivity"/>
    </application>

要访问例如字符串文件,请使用以下代码

App.context?.resources?.getText(R.string.mystring)
于 2019-12-29T06:05:20.830 回答
1

这应该让您可以applicationContext从任何地方访问,让您可以在applicationContext任何可以使用它的地方访问;Toast, getString(),sharedPreferences

单身人士:

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

}

在您的子类中初始化 Singleton 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);
    }
}

如果我没记错的话,这给了你一个到处都是 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"
    >

如果您在这里发现任何问题,请告诉我,谢谢。:)

于 2015-09-25T12:16:17.093 回答
0

不知何故不喜欢存储静态值的 hacky 解决方案,所以想出了一个更长但也可以测试的干净版本。

找到了两种可能的方法-

  1. 将 context.resources 作为参数传递给您想要字符串资源的类。相当简单。如果无法作为参数传递,请使用 setter。

例如

data class MyModel(val resources: Resources) {
    fun getNameString(): String {
        resources.getString(R.string.someString)
    }
}
  1. 使用数据绑定(虽然需要片段/活动)

阅读之前:此版本使用Data binding

XML-

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
    <variable
        name="someStringFetchedFromRes"
        type="String" />
</data>

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{someStringFetchedFromRes}" />
</layout>

活动/片段-

val binding = NameOfYourBinding.inflate(inflater)
binding.someStringFetchedFromRes = resources.getString(R.string.someStringFetchedFromRes)

有时,您需要根据模型中的字段更改文本。因此,您也可以对该模型进行数据绑定,并且由于您的活动/片段知道该模型,因此您可以很好地获取该值,然后基于该值对字符串进行数据绑定。

于 2019-12-19T05:23:12.027 回答
0

如果你想在上下文或活动之外使用 getString,你应该在构造函数或方法参数中有上下文,这样你就可以访问 getstring() 方法。特别是在 Fragment 你应该确保 getActivity() 或 getContext() 不提供空值。要避免片段中的 getActivity() 或 getContext() 为 null,请尝试以下操作:声明一个变量:

Context mContext;

现在覆盖 Fragment 的 onAttach 和 onDetach 方法:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    mContext = context;
}

@Override
public void onDetach() {
    super.onDetach();
    mContext = null;
}

现在在使用 getString() 方法的任何地方使用mContext 。前任:

        Toast.makeText(mContext,  mContext.getString(R.string.sample_toast_from_string_file), Toast.LENGTH_SHORT).show();
于 2021-12-23T18:49:34.983 回答
-3

Kotlin:完美的决定 02.03.2021


  • AppCompatActivity
  • 伴随对象

活动代码:

class MainActivity : AppCompatActivity() {

    companion object {
        lateinit var instance: AppCompatActivity
            private set
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        instance = this
    }
}

从 AnyWhere 获取资源:

val text = MainActivity.instance.getString(R.string.task_1)

PS Vel_daN: 爱​​你所做的。

于 2021-03-02T16:22:16.123 回答
-11

我用 getContext().getApplicationContext().getString(R.string.nameOfString); 它对我有用。

于 2015-02-16T15:14:06.460 回答