Android上下文没有活动?还有其他没有活动的节目?

时间:2013-07-03 06:40:18

标签: android android-activity gps location android-context

我会尽力把它变成一个全面的问题:

我正在编写一个方法来获取一个包含Android设备城市名称的字符串,由LocationManagergetLastKnownLocation()以及所有这些确定。

然后我意识到我需要在另一个活动中再次做同样的事情,所以为什么不在我的程序中创建一个完全独立的类(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,我就无法得到它。当然,我可以作弊,只是输入文字字符串,但这感觉不对。

3 个答案:

答案 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就无法获得

您可以从应用程序上下文中获取它。