একটি প্রসঙ্গ বা ক্রিয়াকলাপের বাইরে গেটস্ট্রিং


260

R.stringআমার কোডের বাইরে হার্ডকোডযুক্ত স্ট্রিংগুলি রাখার জন্য আমি দুর্দান্ত চমত্কার সন্ধান পেয়েছি এবং আমি একটি ইউটিলিটি ক্লাসে এটি ব্যবহার করা চালিয়ে যেতে চাই যা আমার অ্যাপ্লিকেশনটিতে মডেলগুলির সাথে আউটপুট উত্পন্ন করতে কাজ করে। উদাহরণস্বরূপ, এক্ষেত্রে আমি ক্রিয়াকলাপের বাইরে কোনও মডেল থেকে ইমেল উত্পন্ন করছি।

এটি getStringএকটি Contextবা বাইরে ব্যবহার করা সম্ভবActivity ? আমি মনে করি আমি বর্তমান ক্রিয়াকলাপে পাস করতে পারি তবে এটি অপ্রয়োজনীয় বলে মনে হচ্ছে। আমি ভুল হলে আমাকে সংশোধন করুন!

সম্পাদনা করুন: আমরা কি ব্যবহার না করে সংস্থানগুলি অ্যাক্সেস করতে পারি Context?


4
যে স্ট্রিংটি ব্যবহার করতে চলেছে সেই ক্লাসে প্রসঙ্গটি পাস করার মাধ্যমে আপনি অ্যাপটি কী ভাষা (এন, এস, ইত্যাদি) ব্যবহার করছেন সে সম্পর্কেও তথ্য দিয়ে যাচ্ছেন। সুতরাং আপনার যদি দুটি স্ট্রিং.এক্সএমএল থাকে তবে এটি কোনটি ব্যবহার করবেন তা জানতে পারবেন
স্পোর্টস

উত্তর:


440

হ্যাঁ, আমরা `প্রসঙ্গটি ব্যবহার না করেই সংস্থানগুলি অ্যাক্সেস করতে পারি`

তুমি ব্যবহার করতে পার:

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

... আপনার প্রয়োগের সর্বত্র, এমনকি স্থির স্থির ঘোষণাগুলিতে। দুর্ভাগ্যক্রমে, এটি কেবল সিস্টেম সংস্থানগুলিকে সমর্থন করে

স্থানীয় সংস্থানগুলির জন্য এই সমাধানটি ব্যবহার করুন । এটি তুচ্ছ নয়, তবে এটি কার্যকর হয়।


17
সিস্টেম সংস্থান বলতে কী বোঝায়? স্ট্রিং.এক্সএমএল সিস্টেম রিসোর্স নাকি না? আমার জন্য এটি কাজ করে না, বলে সংস্থান খুঁজে পাচ্ছে না।
কির্গগোফ

6
সিস্টেমের সংস্থানগুলি ডিভাইসে অ্যান্ড্রয়েডের অন্তর্ভুক্ত। স্ট্রিং.এক্সএমএল কেবলমাত্র আপনার আবেদনের সাথে সম্পর্কিত। সন্ধান stackoverflow.com/a/4391811/715269 সমাধান
Gangnus

3
স্ট্রিংগুলিতে অ্যাক্সেস করার সময় এই ফ্যাক্টরি ক্লাসগুলির জন্য এটি একটি মার্জিত সমাধান। আমি প্রসঙ্গটি সর্বত্র অতিক্রম করতে পছন্দ করি না। উদাহরণস্বরূপ এটি কেবল অপ্রয়োজনীয় বিশৃঙ্খলা যেখানে আমরা সত্যিকার অর্থে বিশ্বব্যাপী একটি স্ট্রিং চাই।
জে স্নায়দার

1
কোনও ক্লাসে প্রসঙ্গটি প্রেরণ করা এবং এটি ব্যবহার করার চেয়ে এটি কি আরও কার্যকর?
সোলিকিউইড

5
আমি এই ত্রুটিটি android.content.res.Resources$NotFoundException: String resource ID #0x7f0f0061
ইব্রাহিম করিমি

108

দুর্ভাগ্যক্রমে, আপনি যে কোনও স্ট্রিং সংস্থান অ্যাক্সেস করতে পারবেন তার একমাত্র উপায় হ'ল একটি Context(অর্থাত্ একটি Activityবা Service)। আমি সাধারণত এই ক্ষেত্রে যা করেছি, তা হল প্রসঙ্গে কলারকে কেবল পাস করার প্রয়োজন।


4
বখশিশের জন্য ধন্যবাদ! আমি কেবল এটি চেষ্টা করেছি, তবে কোনও কারণে যখন চেষ্টা করেছি তখন একটি সংকলন ত্রুটি পেয়েছি:ctx.getString(ctx.R.string.blah);
নীলা

আমি প্রকারের Contextব্যবহারের পদ্ধতিগুলিতে তর্ক করব যাতে আপনি এটি কোনও কার্যকলাপ বা কোনও পরিষেবা থেকে ব্যবহার করতে পারেন।
ম্যাট্রিক্সফ্রোগ

2
আপনার দরকার নেই ctx.R.string.blah, কেবল ব্যবহার করুনR.string.blah
পেন্টিয়াম

2
কোথা থেকে symbol not found errorআসবে তা আমি নিশ্চিত নই , তবে নিশ্চিত হয়েছি আপনি Rক্লাসের উপরে আমদানি করেছেন।
পেন্টিয়াম

11
উত্তর মিথ্যা। পরেরটি দেখুন। :-)
গাংনুস

33

ইন MyApplication, যা প্রসারিত Application:

public static Resources resources;

ইন MyApplicationএর onCreate:

resources = getResources();

এখন আপনি আপনার প্রয়োগের যে কোনও জায়গা থেকে এই ক্ষেত্রটি ব্যবহার করতে পারেন।


এটি পরিষেবা মাধ্যমে কাজ করবে? (বিশেষত যখন অ্যান্ড্রয়েড অ্যাপ্লিকেশন হত্যা করে এবং কেবল পরিষেবা শুরু করে)
অতুল

1
হ্যাঁ, অ্যান্ড্রয়েড অ্যাপ্লিকেশন.আনক্রিয়েট কল করে আপনার কোডটি কার্যকর করা শুরু করে এবং এর পরে এটি আপনার পরিষেবা চালায়।
konmik

23

বিটিডাব্লু, প্রতীক না পাওয়া ত্রুটির একটি কারণ হতে পারে আপনার আইডিই আমদানি করা অ্যান্ড্রয়েড.আর; আপনার এক পরিবর্তে ক্লাস। শুধু আমদানি 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);
}

19

স্বতন্ত্র পন্থা

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

এটি অ্যাপের সর্বত্র কাজ করবে। ( ইউটিল ক্লাস, ডায়ালগ, টুকরা বা আপনার অ্যাপ্লিকেশনের কোনও শ্রেণি )

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

}

(২) আপনার manifest.xml <applicationট্যাগে নাম ক্ষেত্র যুক্ত করুন ।

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

এখন আপনি যেতে ভাল। App.getRes().getString(R.string.some_id)অ্যাপের যে কোনও জায়গায় ব্যবহার করুন।


1
আমি ব্যক্তিগতভাবে এই পদ্ধতির পছন্দ করি। কোডের যে কোনও জায়গা থেকে কাস্টম স্ট্রিংয়ের সংস্থান পেতে সুবিধাজনক।
চেকমেট 711

এই সমাধানের সাথে কোনও সুরক্ষা সমস্যা আছে?
নিবানবা

@ ব্যবহারকারী 1823280 না, আমি ভাবি না।
খেমরাজ

নিখুঁত সমাধান
ইয়াসিরু নয়নজিৎ

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

0

এটি আপনাকে যে 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;
    }

}

আপনার 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);
    }
}

যদি আমি ভুল না করে, এটি আপনাকে অ্যাপ্লিকেশন 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"
    >

আপনি যদি এখানে কিছু ভুল দেখেন তবে দয়া করে আমাকে জানান, আপনাকে ধন্যবাদ। :)


0

ক্ষেমরাজের প্রতিক্রিয়া থেকে সেরা পন্থা:

অ্যাপ ক্লাস

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

0

প্রসঙ্গ এবং ক্রিয়াকলাপ ছাড়াই এ জাতীয় কিছু ব্যবহার করা ভাল :

Resources.getSystem().getString(R.string.my_text)

0

একরকম স্থিতিশীল মানগুলি সংরক্ষণ করার হ্যাকি সমাধানগুলি পছন্দ হয়নি তাই কিছুটা দীর্ঘ সময় নিয়ে এসেছিল তবে একটি পরিষ্কার সংস্করণ যা পরীক্ষাও করা যেতে পারে।

এটি করার 2 টি সম্ভাব্য উপায় খুঁজে পেয়েছি-

  1. আপনার ক্লাসে যেখানে আপনি স্ট্রিং রিসোর্স চান সেটি প্যারামিটার হিসাবে কনটেক্সট.সোর্সগুলি পাস করুন। মোটামুটি সহজ। যদি প্যারাম হিসাবে পাস করা সম্ভব না হয় তবে সেটারটি ব্যবহার করুন।

যেমন

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>

ভ্রমণ / Fragment-

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

কখনও কখনও, আপনাকে কোনও মডেলের ক্ষেত্রের ভিত্তিতে পাঠ্য পরিবর্তন করতে হবে। সুতরাং আপনি সেই মডেলটিকে ডেটা বেঁধে রাখবেন এবং যেহেতু আপনার ক্রিয়াকলাপ / খণ্ডটি মডেল সম্পর্কে জানে তাই আপনি খুব ভালভাবে মূল্য আনতে পারেন এবং তারপরে স্ট্রিংটিকে ডেটা-বাঁধাই করতে পারেন।


0

আপনি কোটলিনে একটি ক্লাস তৈরি করে এটি করতে পারেন যা অ্যাপ্লিকেশন প্রসারিত করে এবং তারপরে আপনার কোডের যে কোনও জায়গায় সংস্থানগুলিতে কল করার জন্য এর প্রসঙ্গটি ব্যবহার করে

আপনার অ্যাপ্লিকেশন বর্গটি দেখতে এমন হবে

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

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

অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলে আপনার অ্যাপ্লিকেশন ক্লাসটি ঘোষণা করুন (খুব গুরুত্বপূর্ণ)

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

রানটাইম চলাকালীন আপনি যদি স্থানীয়ভাবে প্রোগ্রামটিমেটালি পরিবর্তন করেন তবে এটি কাজ করবে না কারণ যখন আপনার প্রক্রিয়া শুরু হয় তখন অ্যাপ্লিকেশন প্রসঙ্গটি সিঙ্গলটন এবং আরম্ভ হয়।
Szörényi আদম

-2

আমি এখানে যা করেছি তা এখানে, আপনার মূল ক্রিয়াকলাপে, নীচের মত বর্ণিত প্রসঙ্গের জন্য একটি স্ট্যাটিক ভেরিয়েবল তৈরি করুন:

public static Context mContext;

এবং onCreate () এ mContext এর আরম্ভ করুন;

mContext = this;

তারপরে, যে ফাইলটিতে আপনি প্রসঙ্গে অ্যাক্সেস করতে চান সেখানে বলুন,

private Context context = MainActivity.mContext;

এখন, আপনি নিম্নলিখিত পদ্ধতিতে একটি স্ট্রিং রিসোর্স পেতে পারেন,

String myString = context.getResources().getString(R.string.resource_id);

-8

আমি getContext().getApplicationContext().getString(R.string.nameOfString); এটি আমার জন্য কাজ করে।


14
আপনি কি মনে করেন getContext()সব জায়গায় পাওয়া যায় ?!
হামজেহ সোবহ

1
এটি প্রশ্নের উত্তর দেয় না কারণ getContext () কেবলমাত্র ক্রিয়াকলাপ এবং টুকরো টুকরো ক্লাসে উপলব্ধ
উমর আতা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.