我会尽力把它变成一个全面的问题:
我正在编写一个方法来获取一个包含Android设备城市名称的字符串,由LocationManager
和getLastKnownLocation()
以及所有这些确定。
然后我意识到我需要在另一个活动中再次做同样的事情,所以为什么不在我的程序中创建一个完全独立的类(LocationFinder
),而不是在任何地方编写重复的代码?
但是我遇到了困扰我的问题。例如,如果我创建这个类(LocationFinder
),它是否应该扩展Activity,即使它实际上从未实现过可视化?这个类所做的就是拥有各种getter,如getLastKnownCity()
或getCurrentCity()
并返回字符串。我认为它不会扩展Activity类,因为它实际上不是一个活动。
然后我会使用什么Context:
Geocoder geocoder = new Geocoder(Context context, Locale locale)
这使我认为它必须是一项活动。所以我扩展了Activity,并用
替换了构造函数@Override
protected void onCreate(..............
但出于某种原因,即使我放
,也永远不会被调用String city = new LocationFinder().getLastKnownCity();
我的LocationFinder
onCreate()
的第一行是
System.out.println("HEY!")
它从来没有达到那个目的。我在android.internal.os.LoggingPrintStream.println()
和其他东西上得到一个空指针。
另外,还有一堆来自Activity类的系统常量。例如,我需要得到LOCATION_SERVICE
,这是一个字符串,如果没有扩展Activity,我就无法得到它。当然,我可以作弊,只是输入文字字符串,但这感觉不对。
答案 0 :(得分:21)
编辑:如果可能,请使用frogmanx的答案。这只应在他的答案无法使用时使用。 (即直接需要背景的单身人士。)
听起来你应该扩展Application而不是活动。
使你的应用程序像这样:
public class MyApplication extends Application {
private static MyApplication instance;
public MyApplication() {
instance = this;
}
public static MyApplication getInstance() {
return instance;
}
然后将此属性添加到清单的应用程序标记:
<application android:name=".your.package.MyApplication" ... />
毕竟,您可以从任何地方调用MyApplication.getInstance()
来获取上下文。
答案 1 :(得分:13)
构造类时,可以使用构造函数接受Context,并在类中为其指定一个本地Context对象。
public class LocationFinder {
private Context myContext;
private Geocoder geocoder;
public LocationFinder(Context context)
{
myContext = context;
geocoder = new Geocoder(myContext);
}
}
然后当您尝试访问此类时,请确保将其初始化为:
public class TestActivity extends Activity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationFinder lFinder = new LocationFinder(getApplication());
}
}
当然,您无法从将要运行的每个类访问上下文。因此,对View的引用就足够了。
LocationFinder lFinder = new LocationFinder(anyView.getApplication());
答案 2 :(得分:3)
should it extend Activity, even though it is never actually visualized?
没有。来自Android docs
活动是用户可以做的一件重点事。几乎 所有活动都与用户交互,因此Activity类占用 为您创建一个可以放置UI的窗口 的setContentView(查看)
将活动视为用户看到的屏幕。
然后我会使用什么Context Geocoder geocoder = new Geocoder(Context context,Locale locale)
Activity
类扩展Context
,包括Application
在内的许多其他类也是如此。 上下文提供对与扩展上下文的类关联的资源的访问。
只有在需要与与该Activity关联的资源以及由具体Activity类实现的方法进行交互时,才需要且应该仅使用Activity上下文。当您确实需要访问该上下文时,您可以将其传递给需要访问的类,通常作为该类的构造函数的参数。
如果您在扩展它的活动之外传递了Activity上下文,请确保引用的范围和生命周期小于或等于扩展活动,否则如果活动被销毁,您将泄漏大量内存因为垃圾收集器无法释放内存,因为存在对上下文的引用。
如果您看一下Geocoder的构造函数,您会发现它将Context作为参数,如您所知。关于为什么在描述中需要Context,有一条线索:
Geocoder(Context context, Locale locale)
Constructs a Geocoder whose responses will be localized for the given Locale. [1]:
需要Context的原因是访问有关平台区域设置和当前系统区域设置的系统信息。
因此,在您的示例中,您可以简单地将Application上下文传递给构造函数,您可以使用getApplicationContext()
例如,我需要获取LOCATION_SERVICE,这是一个String,如果没有扩展Activity就无法获得
您可以从应用程序上下文中获取它。