[java] 정적 컨텍스트에서 리소스 컨텐츠를 얻으려면 어떻게해야합니까?

위젯 xml과 같은 다른 많은 작업을 수행하기 전에 파일 에서 문자열을 읽고 싶습니다 setText. 따라서 활동 객체를 호출하지 않고 어떻게 할 수 getResources()있습니까?



답변

  1. Application예를 들어 의 하위 클래스를 만듭니다.public class App extends Application {
  2. 태그 의 android:name속성을 새 클래스를 가리 키도록 설정하십시오. 예 :<application>AndroidManifest.xmlandroid:name=".App"
  3. 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())를 사용할 수 있습니다.


답변

시스템 리소스 전용!

사용하다

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

정적 상수 선언에서도 응용 프로그램의 모든 곳에서 사용할 수 있습니다!


답변

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

이 답변을 삭제하지 마십시오. 하나를 유지하겠습니다.


답변

또 다른 가능성이 있습니다. 다음과 같은 리소스에서 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)


답변

싱글 톤 :

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서브 클래스 에서 싱글 톤을 초기화하십시오 :

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.xmlApplication서브 클래스 를 사용 하도록 업데이트하십시오 :

<?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 ()를 사용할 수 있어야하며 응용 프로그램 서브 클래스가없는 곳도 거의 없습니다.

여기에 잘못된 것이 있으면 알려주십시오. 감사합니다. 🙂


답변

다른 해결책 :

비 정적 외부 클래스에 정적 서브 클래스가있는 경우 외부 클래스의 정적 변수를 통해 서브 클래스 내의 자원에 액세스 할 수 있으며,이 클래스는 외부 클래스 작성시 초기화됩니다. 처럼

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 때문에 유용합니다.


답변

지름길

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)코드 어디에서나 사용하십시오 .