স্থিতি প্রসঙ্গে আমি কীভাবে কোনও সংস্থান সামগ্রী পেতে পারি?


168

উইজেটগুলির xmlমতো আরও কিছু করার আগে আমি কোনও ফাইল থেকে স্ট্রিংগুলি পড়তে চাই setText, সুতরাং আমি কীভাবে কোনও অ্যাক্টিভিটি অবজেক্ট না করে তা করতে পারি getResources()?

উত্তর:


373
  1. Applicationউদাহরণস্বরূপ একটি সাবক্লাস তৈরি করুনpublic class App extends Application {
  2. আপনার নতুন শ্রেণীর দিকে নির্দেশ করার android:nameজন্য আপনার <application>ট্যাগের বৈশিষ্ট্যটি সেট করুন AndroidManifest.xmlegandroid: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())।


9
অ্যাপ্লিকেশনটির উদাহরণ একটি গতিশীল মান নয়, তবে @ গাঙ্গনাস কীভাবে? যাই হোক না কেন - আমি শক্ত উপায়টি খুঁজে পেয়েছি যে অ্যান্ড্রয়েডে স্ট্যাটিকের উপর নির্ভর করা মাথা ব্যথার কিছু নয়। "এখন আপনি এটি দেখুন, এখন আপনি পাবেন না"
বোস্টোন

18
আমি এটি 'হ্যাক' তা ভেবে এড়াতে পারি না। তবুও আমি এটি ব্যবহার করছি (বিটিডব্লিউ এই সমাধান দেওয়ার জন্য ধন্যবাদ, যেহেতু আমি স্থানীয়করণকে বহির্মুখী করতে চলেছিলাম) আমি এই খারাপ অনুভূতিটি পেয়েছি, যেমন এটি কোনওভাবেই ভুল।
Illiax

8
আপনার অ্যাপ্লিকেশনটিতে প্রতিটি স্ট্যাটিক পদ্ধতিতে প্রথম পরামিতি হিসাবে কনটেক্সটে পাস করার চেয়ে ভাল বা খারাপ? প্রাক্তন হ্যাকি অনুভব করে তবে শেষোক্ত অযথা পুনরাবৃত্তি হয়।
ডেভ

12
দস্তাবেজগুলি বলেছে "সাধারণত সাবক্লাস অ্যাপ্লিকেশন করার প্রয়োজন হয় না most বেশিরভাগ পরিস্থিতিতে স্থির এককগুলি আরও কার্যকরভাবে একই কার্যকারিতা সরবরাহ করতে পারে your এটিকে একটি প্রসঙ্গ দেওয়া যেতে পারে যা প্রথম সিঙ্গলটন নির্মাণের সময় অভ্যন্তরীণভাবে Context.get ApplicationContext () ব্যবহার করে। " ~ developer.android.com/references/android/app/application.html
ডেভিড ডি সি ই

25
মেমরি ফাঁস এড়ানোর জন্য কনটেক্সটটি একটি WeakReferences এ সংরক্ষণ করা ভাল: ব্যক্তিগত স্ট্যাটিক WeakReferences <কনটেক্সট> এম কনটেক্সট; পাবলিক স্ট্যাটিক কনটেক্সট getContext () {রিটার্ন mContext.get (); App অ্যাপটি ক্র্যাশ হয়ে গেলে এবং আপনি স্থির প্রসঙ্গটি বাতিল করতে পারবেন না এমন ক্ষেত্রে সহায়তা করা উচিত (WeakReferences আবর্জনা সংগ্রহ করা যেতে পারে)।
ফ্রাঙ্কক্রামনো

102

কেবলমাত্র সিস্টেম সংস্থার জন্য!

ব্যবহার

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

আপনি এগুলি স্থির স্থির ঘোষণাপত্রগুলিতে এমনকি আপনার অ্যাপ্লিকেশনের যে কোনও জায়গায় ব্যবহার করতে পারেন!


2
চমৎকার. আমি সাধারণত অসন্তুষ্ট হই না ... যখন কেউ বড় হাতের অক্ষর ব্যবহার করে: পি জাস্ট মজা করে। ওয়েল, আপনার স্ট্যান্ডার্ড স্ট্রিংস এবং ড্রইবেবলের মতো কিছু সংস্থার জন্য কাজ করে ... তবে ডকুমেন্টেশন যেমন বলে, এটি ওরিয়েন্টেশন ব্যবস্থা ইত্যাদির মতো জিনিসগুলির পক্ষে ভাল কাজ করে না এবং সবচেয়ে গুরুত্বপূর্ণ, এটি আপনাকে কোনওরকম হতে দেয় না বৈশ্বিক প্রসঙ্গ যা কখনও কখনও প্রয়োজনীয় জিনিসগুলির জন্য দরকারী হয় ( Toastউদাহরণস্বরূপ উত্থাপন , SharedPreferenceউদাহরণ পাওয়া, একটি ডেটাবেস খুলুন, যেমন আমার লাতিন ভাষার শিক্ষক বলেছেন: ET cetera )।
খ্রিস্টিয়ান

1
আপনি এটি দ্বারা সমস্ত বিশ্বের শান্তি জিততে পারবেন না :-)। তবে এটি এখানে প্রশ্নের দ্বারা নির্ধারিত সমস্যা সমাধানে সহায়তা করে। আমি বলছি না যে এটি প্রতিটি কাজ সলভ করে, কেবল এটি অ্যাপ্লিকেশনের প্রতিটি জায়গাতেই এটির কার্যটি সমাধান করে। আমি 10 মাস ধরে এই জাতীয় সমাধান অনুসন্ধান করেছি - আমি অ্যান্ড্রয়েড ব্যবহারের সর্বদা। এবং এখন আমি এটি খুঁজে পেয়েছি।
গাংনুস

18
আপনার এখানে সাবধানতা অবলম্বন করতে হবে। এই পদ্ধতিটি ব্যবহার করে আপনার অ্যাপ্লিকেশন সংস্থানগুলি সন্ধান করার চেষ্টা করবেন না। সূক্ষ্ম মুদ্রণটি পড়ুন: একটি বিশ্বব্যাপী ভাগ করা রিসোর্সস অবজেক্টটি ফিরিয়ে দিন যা কেবলমাত্র সিস্টেম সংস্থানগুলিতে অ্যাক্সেস সরবরাহ করে (কোনও অ্যাপ্লিকেশন সংস্থান নেই), এবং বর্তমান স্ক্রিনের জন্য কনফিগার করা হয়নি (দিকনির্দেশ ইউনিট ব্যবহার করতে পারে না, অভিমুখের ভিত্তিতে পরিবর্তন করতে পারে না) ইত্যাদি)
বোস্টোন

4
@ DroidIn.net উদ্ধৃতি: "তবে কেবল সিস্টেম সংস্থার জন্য!"। আমি জানি / * দীর্ঘশ্বাস / *
গাংনাস

1
আমি এটি ব্যবহার করে একটি ব্যতিক্রম পেয়েছি: অ্যান্ড্রয়েড.কন্টেন্ট.রেস.সংশ্লিষ্ট $ নটফাউন্ডএক্সেপশন: স্ট্রিং রিসোর্স আইডি
ভিনিডোগ

6

আমার কোটলিন সমাধানটি একটি স্থিতিশীল অ্যাপ্লিকেশন প্রসঙ্গে ব্যবহার করা:

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

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

এবং স্ট্রিংস ক্লাস, যা আমি সর্বত্র ব্যবহার করি:

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

দয়া করে এই উত্তরটি মুছবেন না, আমাকে একটি রাখুন।


সহজ এবং পরিষ্কার সমাধান, কোড ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ!
জীহুত

ধন্যবাদ! যদিও এটি একটি পরিচিত সমাধান, Stringsসহায়ক ছিল।
কুলমাইন্ড

4

অন্য সম্ভাব্যতাও রয়েছে। আমি এই জাতীয় সংস্থান থেকে ওপেনএল শেডারগুলি লোড করি:

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। এটিও আমি পরীক্ষায় সংস্থানগুলি কীভাবে লোড করি (অ্যান্ড্রয়েড টেস্টস)


1
ক্রিয়াকলাপ না থাকাকালীন আমার জন্য একমাত্র সমাধান (অ্যাপ্লিকেশনটি প্রসারিত করতে পারে এমন কোনও ক্লাস ছাড়াই প্লাগিন বিকাশ করা)। আপনাকে +1
Itaton

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সাবক্লাসে সিঙ্গলটনটি শুরু করুন :

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

এখন আপনি অ্যাপ্লিকেশন কনটেক্সটসিংলেটন.জেটআইনস্ট্যান্স ()। GetapplicationContext ()। GetResource () যে কোনও জায়গা থেকে প্রয়োগ করতে পারবেন, খুব কম জায়গা যেখানে অ্যাপ্লিকেশন সাবক্লাসগুলি পারে না।

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


2

আরেকটি সমাধান:

যদি আপনার অ স্থিতিশীল বাইরের শ্রেণিতে একটি স্ট্যাটিক সাবক্লাস থাকে তবে আপনি বাইরের শ্রেণীর স্ট্যাটিক ভেরিয়েবলের মাধ্যমে সাবক্লাসের মধ্য থেকে সংস্থানগুলি অ্যাক্সেস করতে পারেন, যা আপনি বহিরাগত শ্রেণি তৈরির সূচনা করেছিলেন। মত

public class Outerclass {

    static String resource1

    public onCreate() {
        resource1 = getString(R.string.text);
    }

    public static class Innerclass {

        public StringGetter (int num) {
            return resource1; 
        }
    }
}

আমি এটি আমার ফ্র্যাগমেন্টএকটিভিটির মধ্যে স্ট্যাটিক ফ্রেগমেন্টপেজার অ্যাডাপ্টারের getPageTitle (int পজিশন) ফাংশনের জন্য ব্যবহার করেছি যা I8N এর কারণে কার্যকর।


2

শর্টকাট

এর App.getRes()পরিবর্তে আমি ব্যবহার করি App.getContext().getResources()(যেমন ক্রিশ্চিয়ান উত্তর দিয়েছেন)

এটি আপনার কোডের যে কোনও জায়গায় ব্যবহার করা খুব সহজ!

সুতরাং এখানে একটি অনন্য সমাধান যা দ্বারা আপনি যে কোনও জায়গা থেকে সংস্থান অ্যাক্সেস করতে পারেন 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;
    }

}

(২) আপনার manifest.xml <applicationট্যাগে নাম ক্ষেত্র যুক্ত করুন । (বা ইতিমধ্যে সেখানে থাকলে এড়িয়ে যান)

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

এখন আপনি যেতে ভাল।

App.getRes().getString(R.string.some_id)কোড যে কোনও জায়গায় ব্যবহার করুন।


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

আমি স্ট্যাটিক ফাংশন থেকে ওপেনজিএল ইএস এর জন্য শেডার লোড করি।

মনে রাখবেন আপনার ফাইল এবং ডিরেক্টরি নামের জন্য আপনাকে অবশ্যই ছোট কেস ব্যবহার করতে হবে, না হলে অপারেশন ব্যর্থ হবে

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() : "";
    }

    ...

}

0
public Static Resources mResources;

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

ঠিক আছে, সমস্যাটি হ'ল getResferences () এর একটি প্রসঙ্গ প্রয়োজন। সুতরাং এটি সম্ভবত "কোনও ক্রিয়াকলাপের অবজেক্ট ছাড়াই" (যার জন্য আপনি অনক্রিট () পদ্ধতিটি পোস্ট করেছেন) এর জন্য কোনও দ্রাবণ নয়
টোবিয়াস রিখ

0

আমি এপিআই স্তর 27 ব্যবহার করছি এবং প্রায় দুই দিন লড়াইয়ের পরে একটি সেরা সমাধান পেয়েছি। আপনি যদি কোনও ক্লাস থেকে কোনও এক্সএমএল ফাইলটি পড়তে চান যা ক্রিয়াকলাপ বা অ্যাপ্লিকেশন থেকে আসে না তবে নিম্নলিখিতটি করুন।

  1. সম্পত্তি ডিরেক্টরি ডিরেক্টরিতে টেস্টডেটা.এক্সএমএল ফাইলটি রাখুন।

  2. টেস্টডাটা ডকুমেন্টটি পার্স করার জন্য নিম্নলিখিত কোডটি লিখুন।

        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

আপনার ক্লাসে, যেখানে আপনি স্থির ফাংশন প্রয়োগ করেন , আপনি এই শ্রেণি থেকে একটি ব্যক্তিগত a পাবলিক পদ্ধতিতে কল করতে পারেন । বেসরকারী \ সর্বজনীন পদ্ধতিটি getResource অ্যাক্সেস করতে পারে

উদাহরণ স্বরূপ:

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

-1

আপনার যদি প্রসঙ্গ থাকে তবে আমার অর্থ ভিতরে;

public void onReceive(Context context, Intent intent){

}

আপনি সংস্থান পেতে এই কোডটি ব্যবহার করতে পারেন:

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

2
প্রশ্নের শিরোনাম একটি স্থির প্রসঙ্গে বলে says যা আপনার উত্তরটি কভার করে না।
রুন শেজেলরূপ ফিলোসোফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.