Android 在非活动类中使用getResources()

Android 在非活动类中使用getResources(),android,android-context,Android,Android Context,我试图在非活动类中使用getResources方法。如何获取对“resources”对象的引用,以便访问存储在resources文件夹下的xml文件 例如: XmlPullParser xpp = getResources().getXml(R.xml.samplexml); 您必须将上下文对象传递给它。如果在activty中有对类的引用,则this,或者getApplicationContext() 然后可以在构造函数中使用它(或将其设置为实例变量): 如果构造函数接受上下文作为参数,则可以

我试图在非活动类中使用getResources方法。如何获取对“resources”对象的引用,以便访问存储在resources文件夹下的xml文件

例如:

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

您必须将
上下文
对象传递给它。如果在activty中有对类的引用,则
this
,或者
getApplicationContext()

然后可以在构造函数中使用它(或将其设置为实例变量):


如果构造函数接受
上下文
作为参数

,则可以使用

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

好吧,不需要传递上下文,也不需要做所有这些……只需这样做

Context context = parent.getContext();

编辑:其中父视图是视图组

传递
上下文
对象不是一个好主意。这通常会导致内存泄漏。我的建议是你不要这样做。我已经制作了许多Android应用程序,而不必将上下文传递给应用程序中的非活动类。一个更好的办法是在
活动
片段
中获取您需要访问的资源,并在另一个类中保留它。然后,您可以在应用程序中的任何其他类中使用该类来访问资源,而无需传递
上下文
对象。

这对我来说总是有效的:

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);
        WigetControl control = new WigetControl(getResources());
        control.setButtonDisable(btNext);
以下是我的答案:

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

电话可以是这样的:

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);
        WigetControl control = new WigetControl(getResources());
        control.setButtonDisable(btNext);

还有一种方法不用创建对象。检查一下。谢谢@cristian。下面我添加了上述参考中提到的步骤。对我来说,我不想为它创建一个对象并访问它。因此,我尝试在不创建对象的情况下访问
getResources()
。我找到了这个帖子。所以我想加上它作为答案

按照以下步骤访问非活动类
中的
getResources()
,而不通过对象传递上下文

  • 创建一个子类,例如
    公共类App extends Application{
    。请参阅步骤旁边的代码
  • AndroidManifest.xml
    中设置
    android:name
    标记的
    属性以指向新类,例如
    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;
    }
}

在Udacity的基础ANdroid课程的导游应用程序中,我使用了片段的概念。我在访问字符串、xml文件中描述的一些字符串资源时遇到了困难。最终找到了解决方案

这是主要的活动课

package 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 
}
}
这是扩展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];
}
}

我们可以使用像这样的上下文,在父视图组中立即尝试

Context context = parent.getContext();

在简单类中,声明上下文并从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

        }
}
在activity类中,像这样声明

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(),而不是将活动上下文(即此上下文)传递给singleton类

选项2:如果确实必须使用活动上下文,那么当活动被销毁时,请确保传递给singleton类的上下文设置为null

希望能有帮助。。∆∆∆∆

在您的主要活动中:

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

在Android中传递
Context
对象通常不是一个好主意。这可能会导致内存泄漏。请参阅我的答案,以获得风险较小的解决方案。在Android中传递
Context
对象可能是重复的,通常不是一个好主意。它可能会导致内存泄漏。基本经验法则是肯定的,但我觉得这有点困难误导性。
Context
对象是令人讨厌的,因为它在应用程序范围或活动范围内并不明显。内存泄漏(和崩溃)当您提供错误的时发生。例如,向需要
上下文的静态对象提供
活动
,并且当
活动
发生时,所述对象不会被销毁,从而导致在onDestroy后持续存在
活动
,因为它由于此其他静态对象而无法进行GCD。因此,是的,它可能是危险的罗丝,但是知道为什么它是危险的,我觉得在这里提及是很重要的。^Dororo,这是我读过的最重要的评论之一。正确使用上下文很少被讨论。我觉得我因为它有很多无法解释的错误!@Dororo,你有什么练习建议吗?我们应该避免传递上下文吗变量?那么,当我们需要活动类中的一些api时,我们可以做什么呢?请注意,您可以按照此方法注入资源(定义一个接受
@ApplicationContext:context的提供程序,并返回
context.resources
)这在使用数据库存储库时特别有用,您应该已经在其中注入了。这是一个很好的建议,谢谢。SQLiteOpenHelper中会有问题吗?在构造函数中,您必须传递一个上下文。它在其他方法中不再可用,但我可以将其存储在私有字段中。@Peter是的,有些类需要您需要传递一个上下文对象,所以最好在活动或片段中只使用像SqLiteOpenHelper这样的类,这样您就不必传递aro