我正在尝试在非活动类中使用getResources方法。如何获得对“资源”对象的引用,以便可以访问资源文件夹下存储的xml文件?
例:
XmlPullParser xpp = getResources().getXml(R.xml.samplexml);
我正在尝试在非活动类中使用getResources方法。如何获得对“资源”对象的引用,以便可以访问资源文件夹下存储的xml文件?
例:
XmlPullParser xpp = getResources().getXml(R.xml.samplexml);
Answers:
您将必须将一个context
对象传递给它。要么this
,如果你有在activty到类的引用,或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
需要a的静态对象提供an ,Context
并且当Activity
is导致Activity
在onDestroy之后持续存在时,该对象不会被销毁,因为由于另一个静态对象而无法对其进行GC处理。所以是的,这可能很危险,但是在这里要提到我知道为什么感到危险的重要性。
传递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);
在Udacity的基础ANdroid课程的导游应用程序中,我使用了片段的概念。我遇到了一段时间,难以访问以字符串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
}
}
这是扩展FragmentPageAdapter的非Activity类
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()而不是将活动上下文(即活动上下文)传递给singleton类。
选项2:如果您确实必须使用活动上下文,那么在销毁活动时,请确保将传递给singleton类的上下文设置为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();
}
}
}
ResourcesHelper:
public class ResourcesHelper {
public static Resources resources;
}
然后到处使用
String s = ResourcesHelper.resources.getString(R.string.app_name);
Context
在Android中传递对象通常不是一个好主意。它可能导致内存泄漏。请参阅我的答案,以寻求风险较小的解决方案。