Я пытаюсь использовать метод getResources в неактивном классе. Как мне получить ссылку на объект «ресурсы», чтобы получить доступ к XML-файлу, хранящемуся в папке ресурсов?
Пример:
XmlPullParser xpp = getResources().getXml(R.xml.samplexml);
Я пытаюсь использовать метод getResources в неактивном классе. Как мне получить ссылку на объект «ресурсы», чтобы получить доступ к XML-файлу, хранящемуся в папке ресурсов?
Пример:
XmlPullParser xpp = getResources().getXml(R.xml.samplexml);
Ответы:
Вам нужно будет передать ему 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
в качестве параметра
Context
объекты в Android. Это может привести к утечке памяти.
Context
объекты неприятны, потому что не сразу очевидно, является ли это общими для приложения или для всей деятельности. Утечки памяти (и сбои) происходят, когда вы вставляете неправильный. Например, передача Activity
статическому объекту, который нуждается, Context
и указанный объект не уничтожается, когда Activity
это приводит к Activity
сохранению после onDestroy, поскольку он не может быть собран из-за этого другого статического объекта. Так что да, это может быть опасно, но я считаю важным упомянуть , зная, почему это опасно.
Не рекомендуется передавать Context
предметы вокруг. Это часто приводит к утечкам памяти. Я предлагаю вам не делать этого. Я создал множество приложений для Android без необходимости передавать контекст неактивным классам в приложении. Лучшей идеей было бы получить ресурсы, к которым вам нужен доступ, пока вы находитесь в Activity
или Fragment
, и удержать их в другом классе. Затем вы можете использовать этот класс в любых других классах вашего приложения для доступа к ресурсам без необходимости передавать Context
объекты.
Есть еще один способ без создания объекта. Проверить ссылку . Спасибо за @cristian. Ниже я добавляю шаги, упомянутые в приведенной выше ссылке. Мне не нравится создавать для этого объект и получать доступ. Поэтому я попытался получить доступ к файлу getResources()
без создания объекта. Я нашел этот пост. Поэтому я подумал добавить это в качестве ответа.
Следуйте инструкциям, чтобы получить доступ getResources()
в неактивном классе without passing a context
через объект.
Application
, например, подкласс public class App extends Application {
. См. Код рядом с шагами.android:name
атрибут вашего <application>
тега в, AndroidManifest.xml
чтобы указать на ваш новый класс, напримерandroid: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;
}
}
вот мой ответ:
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);
это можно сделать, используя
context.getResources().getXml(R.xml.samplexml);
Context
предметов - нездоровая практика,
Мы можем использовать контекст. Как это, попробуйте сейчас. Где родительский элемент - это ViewGroup.
Context context = parent.getContext();
ну нет необходимости передавать контекст и делать все это ... просто сделайте это
Context context = parent.getContext();
Изменить: где родительский элемент - это ViewGroup
У меня это всегда работает:
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);
В приложении-гиде базового курса ANdroid от Udacity я использовал концепцию фрагментов. Я застрял на некоторое время, испытывая трудности с доступом к некоторым строковым ресурсам, описанным в strings, xml файле. Наконец нашел решение.
Это основной вид деятельности
пакет com.example.android.tourguidekolkata;
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
}
}
Это не класс Activity, который расширяет FragmentPageAdapter
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];
}
}
В простом классе объявить контекст и получить данные из файла из папки res
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);
}
}
Я опаздываю, но полное решение; Пример класса, используйте такой контекст: -
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. Вместо передачи контекста активности, то есть в одноэлементный класс, вы можете передать applicationContext ().
Вариант 2: если вам действительно нужно использовать контекст активности, то при уничтожении активности убедитесь, что для контекста, который вы передали в одноэлементный класс, установлено значение null.
Надеюсь, это поможет .. ∆∆∆∆
в вашем MainActivity:
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);
Context
объекты в Android. Это может привести к утечке памяти. См. Мой ответ, чтобы найти менее рискованное решение.