অ-অ্যাক্টিভিটি ক্লাসে getRes Source () ব্যবহার করা


123

আমি একটি অ-অ্যাক্টিভিটি ক্লাসে getResferences পদ্ধতি ব্যবহার করার চেষ্টা করছি। আমি কীভাবে "সংস্থানগুলি" অবজেক্টের রেফারেন্স পেতে পারি যাতে আমি রিসোর্স ফোল্ডারের অধীনে থাকা এক্সএমএল ফাইলটি অ্যাক্সেস করতে পারি?

উদাহরণ:

XmlPullParser xpp = getResources().getXml(R.xml.samplexml);

সাধারণত Contextঅ্যান্ড্রয়েডে অবজেক্টগুলির কাছাকাছি যাওয়া ভাল ধারণা নয় । এটি স্মৃতি ফাঁস হতে পারে। কম ঝুঁকিপূর্ণ সমাধানের জন্য আমার উত্তরটি দেখুন।
জেসন ক্রসবি

উত্তর:


147

contextআপনাকে এটিতে কোনও বস্তু পাস করতে হবে। হয় thisযদি আপনার কোনও ক্রিয়াকলাপে শ্রেণীর রেফারেন্স থাকে, বাgetApplicationContext()

public class MyActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        RegularClass regularClass = new RegularClass(this);
    }
}

তারপরে আপনি এটি কনস্ট্রাক্টারে ব্যবহার করতে পারেন (বা এটি উদাহরণের পরিবর্তনশীলতে সেট করুন):

public class RegularClass(){
    private Context context;

    public RegularClass(Context current){
        this.context = current;
    }

    public findResource(){
        context.getResources().getXml(R.xml.samplexml);
    }
}

যেখানে কনস্ট্রাক্টর Contextপ্যারামিটার হিসাবে গ্রহণ করে


7
সাধারণত Contextঅ্যান্ড্রয়েডে অবজেক্টগুলির কাছাকাছি যাওয়া ভাল ধারণা নয় । এটি স্মৃতি ফাঁস হতে পারে।
জেসন ক্রসবি

28
থাম্বের প্রাথমিক নিয়ম হিসাবে নিশ্চিত, তবে আমি এটি কিছুটা বিভ্রান্তিকর বলে মনে করি। Contextঅবজেক্টগুলি অদ্ভুত কারণ এটি তাত্ক্ষণিকভাবে স্পষ্ট হয় না যদি এটি অ্যাপ্লিকেশন-ব্যাপী বা কার্যকলাপ-বিস্তৃত হয়। মেমরি ফাঁস (এবং ক্র্যাশগুলি) ঘটে যখন আপনি ভুল সরবরাহ করে। উদাহরণস্বরূপ, যদি একটি সরবরাহ Activityএকটি স্ট্যাটিক বস্তুর যা এর প্রয়োজন Contextবললেন বস্তুর ধ্বংস হয় না, যখন Activityবাড়ে Activityঅন্য স্ট্যাটিক বস্তুর কারণে onDestroy পর অমীমাংসিত সমস্যা, যেহেতু এটি GCed হতে পারে না। সুতরাং হ্যাঁ, এটি বিপজ্জনক হতে পারে তবে কেন এটি বিপজ্জনক বলে আমি জানার বিষয়টি এখানে উল্লেখ করা গুরুত্বপূর্ণ।
ডোররো

2
Or দোরোরো, এটি আমি পড়েছি এমন একটি গুরুত্বপূর্ণ মন্তব্য। প্রসঙ্গে যথাযথ ব্যবহার খুব কম ক্ষেত্রেই হয়, যদি আলোচনা হয়। আমি অনুভূতি পেয়েছি যে এর কারণে আমার অনেকগুলি অনির্বচনীয় ত্রুটি হয়েছে!
জোনাথন ডান

@ দোরো তাহলে আপনার কাছে কোন অনুশীলনের পরামর্শ আছে? আমাদের কি প্রসঙ্গ ভেরিয়েবলগুলি পাস করার চেষ্টা করা উচিত? তারপরে অ্যাক্টিভিটি ক্লাস থেকে কিছু এপিআই দরকার হলে আমরা কী করতে পারি?
অ্যালস্টন

35

Contextচারপাশে বস্তুগুলি পাস করা ভাল ধারণা নয় । এটি প্রায়শই স্মৃতি ফাঁস হতে পারে। আমার পরামর্শ হ'ল আপনি এটি করবেন না। আমি অ্যাপটিতে অ-অ্যাক্টিভিটি ক্লাসে প্রসঙ্গ ছাড়াই অসংখ্য Android অ্যাপ তৈরি করেছি। আরও ভাল ধারণা হ'ল আপনার Activityবা আপনার থাকার সময়ে যে সংস্থানগুলি অ্যাক্সেস করা দরকার সেগুলি পাওয়া Fragmentএবং এটি অন্য কোনও ক্লাসে ধরে রাখা। তারপরে আপনি আপনার অ্যাপ্লিকেশানের অন্য কোনও ক্লাসে সেই শ্রেণীর সাহায্যে অ্যাক্সেসগুলি অ্যাক্সেসের জন্য ব্যবহার করতে পারেন, Contextঅবজেক্টগুলির আশপাশ ছাড়াই ।


এটি ভাল পরামর্শ ধন্যবাদ। এটি কি কোনও এসকিউএলওপেনহেল্পারে সমস্যা হবে? কনস্ট্রাক্টরে আপনাকে একটি প্রসঙ্গ পাস করতে হবে। এটি অন্য পদ্ধতিগুলিতে আর উপলভ্য নয় তবে আমি এটি একটি ব্যক্তিগত ক্ষেত্রে সংরক্ষণ করতে পারি।
পিটার

2
@ পিটার হ্যাঁ কিছু ক্লাস রয়েছে যার জন্য আপনাকে একটি প্রসঙ্গ অবজেক্টে পাস করতে হবে। সুতরাং সেক্লাইটঅপেনহেল্প্পার মতো ক্লাসগুলি কেবল কোনও ক্রিয়াকলাপ বা টুকরোটিতে ব্যবহার করার চেষ্টা করা সবচেয়ে ভাল যাতে আপনার প্রসঙ্গের অবজেক্টের পাশ দিয়ে যেতে হবে না। যদি এটি অনিবার্য হয় কেবল মেমরি ফুটো হওয়ার ঝুঁকি কমাতে সহায়তা করার জন্য আপনি যদি প্রাসঙ্গিক অবজেক্টের জন্য আপনার রেফারেন্সটি বাতিল করে দেয় তা নিশ্চিত করে নিন।
জেসন ক্রসবি

1
প্রসঙ্গের অবজেক্টটি অতিক্রম করা সর্বদা খারাপ নয়, যতক্ষণ আপনি ক্রিয়াকলাপের জীবনচক্রটি পর্যবেক্ষণ করতে পারেন। যদি না হয় তবে মেমরি ফাঁস এড়াতে getApplicationContext () ব্যবহার করে ক্রিয়াকলাপের প্রসঙ্গের পরিবর্তে অ্যাপ্লিকেশন প্রসঙ্গটি ব্যবহার না করে আরও ভাল ব্যবহার করুন। অ্যাপ্লিকেশন প্রসঙ্গে পুনরুদ্ধারের জন্য stackoverflow.com/questions/7144177/… দেখুন ।
ফ্রোজেনফায়ার

14

অবজেক্ট তৈরি না করেই আরও একটি উপায় রয়েছে। রেফারেন্স পরীক্ষা করুন । @ ক্রিশ্চিয়ানের জন্য ধন্যবাদ। নীচে আমি উপরোক্ত রেফারেন্সে উল্লিখিত পদক্ষেপগুলি যুক্ত করব। আমার জন্য আমি এটির জন্য অ্যাক্সেস তৈরি করতে এবং অ্যাক্সেস করতে পছন্দ করি না। সুতরাং আমি getResources()কোনও অবজেক্ট তৈরি না করেই অ্যাক্সেস করার চেষ্টা করেছি । আমি এই পোস্ট পেয়েছি। সুতরাং আমি এটি একটি উত্তর হিসাবে যুক্ত করার চিন্তা।

অবজেক্টের মাধ্যমে getResources()অ অ্যাক্টিভিটি ক্লাসে অ্যাক্সেসের পদক্ষেপগুলি অনুসরণ করুন without passing a context

  • Applicationউদাহরণস্বরূপ একটি সাবক্লাস তৈরি করুন public class App extends Application {। পদক্ষেপের পাশের কোডটি দেখুন।
  • আপনার নতুন শ্রেণীর দিকে নির্দেশ করার android:nameজন্য আপনার <application>ট্যাগের বৈশিষ্ট্যটি সেট করুন AndroidManifest.xmlegandroid:name=".App"
  • ইন onCreate()আপনার অ্যাপ উদাহরণস্বরূপ পদ্ধতি, আপনার কনটেক্সট (যেমন সংরক্ষণ thisনামে একটি স্ট্যাটিক মাঠে) appএবং একটি স্ট্যাটিক পদ্ধতি তৈরি করে আয় এই ক্ষেত্রে, যেমন getContext()
  • এখন আপনি ব্যবহার করতে পারেন: App.getContext()যখনই আপনি একটি প্রসঙ্গ পেতে চান এবং তারপরে আমরা App.getContext().getResources()সংস্থানগুলি থেকে মান পেতে ব্যবহার করতে পারি।

এটি দেখতে যেমন হবে:

public class App extends Application{

    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    public static Context getContext(){
        return mContext;
    }
}

5

এখানে আমার উত্তর:

public class WigetControl {
private Resources res;

public WigetControl(Resources res) 
{
    this.res = res;
}

public void setButtonDisable(Button mButton)
{
    mButton.setBackgroundColor(res.getColor(R.color.loginbutton_unclickable));
    mButton.setEnabled(false);
}

}

এবং কলটি এর মতো হতে পারে:

        WigetControl control = new WigetControl(getResources());
        control.setButtonDisable(btNext);

3

এটি ব্যবহার করে করা যেতে পারে

context.getResources().getXml(R.xml.samplexml);

ঠিক আছে, এটি আমার জন্য যাদু করেছে। ধন্যবাদ @ আরশা
কেনি

Contextঅবজেক্টগুলি পাস করা কোনও স্বাস্থ্যকর অনুশীলন নয়
ভেমুরি পাভান

3

আমরা প্রসঙ্গটি ব্যবহার করতে পারি এটির মতো এখনই চেষ্টা করুন যেখানে পিতামাতারা ভিউগ্রুপ rou

Context context = parent.getContext();

1

ভাল প্রসঙ্গটি পাস করার প্রয়োজন নেই এবং যা কিছু করা দরকার ... কেবল এটি করুন

Context context = parent.getContext();

সম্পাদনা করুন: যেখানে অভিভাবকরা ভিউগ্রুপ


3
আমি প্রত্যাশা করি যে আপনি সুবিধাজনক 'ভিউগ্রুপ পিতামাতার' সদস্য ভেরিয়েবলটি ধরে নিয়েছেন বলে ধরে নেওয়া হয়েছিল। বরং বোকা ধারণা।
ARNT

1

এটি সর্বদা আমার পক্ষে কাজ করে:

import android.app.Activity;
import android.content.Context;

public class yourClass {

 Context ctx;

 public yourClass (Handler handler, Context context) {
 super(handler);
    ctx = context;
 }

 //Use context (ctx) in your code like this:
 XmlPullParser xpp = ctx.getResources().getXml(R.xml.samplexml);
 //OR
 final Intent intent = new Intent(ctx, MainActivity.class);
 //OR
 NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
 //ETC...

}

এই প্রশ্নের সাথে সম্পর্কিত নয় তবে উদাহরণস্বরূপ সিস্টেম সংস্থান / ক্রিয়াকলাপটি অ্যাক্সেস করতে একটি টুকরা ব্যবহার করে:

public boolean onQueryTextChange(String newText) {
 Activity activity = getActivity();
 Context context = activity.getApplicationContext();
 returnSomething(newText);
 return false;
}

View customerInfo = getActivity().getLayoutInflater().inflate(R.layout.main_layout_items, itemsLayout, false);
 itemsLayout.addView(customerInfo);

1

উদাসিতার বেসিক এ্যানড্রয়েড কোর্সের ট্যুর গাইড অ্যাপটিতে আমি টুকরো ধারণাটি ব্যবহার করেছি। স্ট্রিংস, এক্সএমএল ফাইলে বর্ণিত কিছু স্ট্রিং রিসোর্সগুলি অ্যাক্সেস করতে অসুবিধার সম্মুখীন হয়ে আমি কিছুক্ষণ আটকে গেলাম। অবশেষে একটি সমাধান পেয়েছি।

এটি মূল ক্রিয়াকলাপ শ্রেণি

প্যাকেজ com.example.android.tourguidek কলকাতা;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState)
{
  //lines of code
   //lines of code
    //lines of code
    YourClass adapter = new YourClass(getSupportFragmentManager(), getApplicationContext()); 
    //lines of code
    // getApplicationContext() method passses the Context of main activity to the class TourFragmentPageAdapter 
}
}

এটি অ-ক্রিয়াকলাপ শ্রেণি যা ফ্রেগমেন্টপেজএডাপ্টার প্রসারিত করে

public class YourClass extends FragmentPagerAdapter {
private String yourStringArray[] = new String[4];
Context context;

public YourClass (FragmentManager fm, Context context)
{
    super(fm);
    this.context = context; // store the context of main activity
    // now you can use this context to access any resource 
    yourStringArray[0] = context.getResources().getString(R.string.tab1);
    yourStringArray[1] = context.getResources().getString(R.string.tab2);
    yourStringArray[2] = context.getResources().getString(R.string.tab3);
    yourStringArray[3] = context.getResources().getString(R.string.tab4);
}
@Override
public Fragment getItem(int position)
 {
 }
@Override
public int getCount() {
return 4;
}

@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return yourStringArras[position];
}
}

0

সাধারণ ক্লাসে প্রসঙ্গ ঘোষণা করুন এবং রেজ ফোল্ডার থেকে ফাইল থেকে ডেটা পান

public class FileData
{
      private Context context;

        public FileData(Context current){
            this.context = current;
        }
        void  getData()
        {
        InputStream in = context.getResources().openRawResource(R.raw.file11);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        //write stuff to get Data

        }
}

ক্রিয়াকলাপ শ্রেণিতে এইভাবে ঘোষণা করুন

public class MainActivity extends AppCompatActivity 
{
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        FileData fileData=new FileData(this);
     }

}

0

আমি দেরীতে হলেও সম্পূর্ণ সমাধান ;: উদাহরণ শ্রেণি, প্রসঙ্গটি এর মতো ব্যবহার করুন: -

public class SingletonSampleClass {

    // Your cute context
    private Context context;
    private static SingletonSampleClass instance;

  // Pass as Constructor
    private SingletonSampleClass(Context context) {
        this.context = context;
    }

    public synchronized static SingletonSampleClass getInstance(Context context) {
        if (instance == null) instance = new SingletonSampleClass(context);
        return instance;
    }

//At end, don't forgot to relase memory
    public void onDestroy() {
       if(context != null) {
          context = null; 
       }
    }
}

সতর্কতা (স্মৃতি ফাঁস)

কীভাবে সমাধান করবেন?

বিকল্প 1 : ক্রিয়াকলাপের প্রসঙ্গটি অর্থাৎ সিঙ্গলটন ক্লাসে পাস করার পরিবর্তে আপনি অ্যাপ্লিকেশন কনটেক্সট () পাস করতে পারবেন।

বিকল্প 2: যদি আপনার যদি সত্যই ক্রিয়াকলাপের প্রসঙ্গটি ব্যবহার করতে হয়, তবে ক্রিয়াকলাপটি ধ্বংস হয়ে যাওয়ার পরে, আপনি সিঙ্গলটন শ্রেণিতে যে প্রসঙ্গটি পাস করেছেন তা বাতিল হয়ে গেছে তা নিশ্চিত করুন।

আশা করি এটি সাহায্য করবে..∆∆∆∆


0

আপনার মূল কার্যকলাপে:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(ResourcesHelper.resources == null){
             ResourcesHelper.resources = getResources();
        }
    }
}

রিসোর্সস হেল্পার:

public class ResourcesHelper {
    public static Resources resources;
}

তারপরে এটি সর্বত্র ব্যবহার করুন

String s = ResourcesHelper.resources.getString(R.string.app_name);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.