如何获得我的活动上下文?


75

我并没有真正理解整个事情是如何工作的,因此,如果我有一些A需要B扩展的类的上下文的类,Activity我如何获得该上下文?

我正在寻找一种比将上下文作为类A构造函数的参数更有效的方法。例如,如果类A将具有数百万个实例,那么我们最终将具有数以百万计的冗余指针,Context而我们应该能够以某种方式仅在某个地方放置一个getter函数。


4
classA。这是您的Activity上下文。
Padma Kumar 2012年

但是,为什么在B类中需要A上下文?
Rakesh 2012年

2
@Rakesh你弄错了……他需要A类中的B上下文(这不会扩展Activity)。这是普遍现象。
Cristian 2012年

Answers:


43

您可以使用Applicationclass(android.application包中的public class),即:

需要维护全局应用程序状态的人员的基类。您可以通过在AndroidManifest.xml的标签中指定其名称来提供自己的实现,这将在创建应用程序/包的过程时为您实例化该类。

要使用此类,请执行以下操作:

public class App extends Application {

    private static Context mContext;

    public static Context getContext() {
        return mContext;
    }

    public static void setContext(Context mContext) {
        this.mContext = mContext;
    }

    ...

}

在您的清单中:

<application
        android:icon="..."
        android:label="..."
        android:name="com.example.yourmainpackagename.App" >
                       class that extends Application ^^^

在活动B中:

public class B extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sampleactivitylayout);

        App.setContext(this);
                  ...
        }
...
}

在A类中:

Context c = App.getContext();

注意事项

通常不需要子类化Application。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。如果您的单身人士需要全局上下文(例如,注册广播接收者),则可以为该函数提供一个上下文,该上下文在首次构造单身人士时在内部使用Context.getApplicationContext()。


4
请问为什么需要实现OnInitListener?
akari 2014年

另外,由于您的应用程序可能具有主要活动(我的名字叫MainActivity),因此您可以将静态Context成员放入该类中。(仅仅是因为您已经创建了该自定义类,所以不需要再创建另一个类,App。)另一方面,将App与无关的东西放进去显然更清晰MainActivity
制造商史蒂夫(Steve),2015年

1
无论哪种方式,当B类消失时,将static设置为null很重要。否则,直到您的应用退出,该B类实例(可能包含大量资源的活动)才会被GC处理。(如果B类是您的主要活动,并且您确实希望保留它,直到您的应用程序退出,请忽略此注释。)
ToolmakerSteve

3
将上下文保持为静态可能会导致Android中的内存泄漏。
Marc Bacvanski '16

OnInitListener那是贴花的TextToSpeech.OnInitListener
亚诺斯

53

好的,我将举一个小例子来说明您的要求

public class ClassB extends Activity
{

 ClassA A1 = new ClassA(this); // for activity context

 ClassA A2 = new ClassA(getApplicationContext());  // for application context. 

}

非常感谢!比使用Application类更好。
Acuna

34

获取活动上下文的最佳和简便方法是在“活动”.this的名称后面加上。例如:如果您的活动名称为SecondActivity,则其上下文将为SecondActivity.this


我想知道此解决方案与更复杂的接受解决方案之间有什么区别-如果根本没有区别。
David Gay

1
@DavidGay getApplicationContext返回整个应用程序的上下文,不建议使用它,至少您需要获取应用程序上下文
John Alexander Betts

@John Alexander Betts谢谢!这应该是公认的答案,并且应该获得最高的投票。这是一个非常简单直接的答案,实际上可以回答OP的问题,而不是被接受为答案的复杂,不清楚,容易出错的类似hack的解决方案。
签名

3

您将上下文传递给其构造函数中的类B,并确保传递getApplicationContext()而不是activityContext()


2
applicationContext和活动上下文不同,它们具有不同的寿命,您应该相应地使用它。
2012年

@Gan完全取决于B类的意义;我以某种方式只是假设ApplicationContext比活动上下文更有用。但这就是我:)
鲨鱼

@Shark:应用程序上下文仅是部分上下文,不适用于特定于UI相关操作的某些事情。
Squonk 2012年

@Squonk您能列举几个吗?我还没有遇到应用程序上下文失败而活动上下文没有失败的情况。
鲨鱼2012年

2
@Shark:对不起,我说的很不好。如果仅要求具有,Context则应用程序上下文或活动上下文都将起作用。但是,如果通过上下文传递的类是可能与UI相关的工作的“帮助程序”类,则ctx.getWindowManager()(例如)如果ctx引用了应用程序上下文,则将不是有效的方法调用。换句话说,它实际上取决于为什么需要向类传递“上下文”以及它需要什么。
Squonk 2012年

2

您可以使用类A的参数Context创建一个构造函数,然后可以使用此上下文。

上下文c;

A(上下文上下文){this.c = context}

在B活动中,使用此构造函数并传递getApplicationContext()创建类A的对象。


1

如果您需要B中A的上下文,则需要将其传递给B,然后可以像其他建议的那样通过将Activity A作为参数传递来做到这一点。我没有看到让A的许多实例拥有自己的B指针的问题,也不确定是否会产生那么多的开销。

但是,如果这是问题所在,则有可能Application像@hasanghaforian所建议的那样,将指向A的指针保留为该类的一种全局变量。实际上,根据您需要上下文的内容,您甚至可以使用Application

我建议阅读这篇有关上下文的文章,以更好地弄清楚您需要什么上下文。


1
由于这比已接受的答案晚了一年,后者已经详细显示了如何执行此操作,因此这不应是单独的答案:唯一的“新”部分是最后一句话,其中包含有用的链接。最好将其作为对已接受答案的评论
制造商

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.