繁体   English   中英

在API中使用静态工厂方法

[英]Use static factory method in API

我正在编写一个基本上是单个自定义活动的小型库:

package com.example.android.somelibrary;

public class CustomActivity extends Activity {

    private static final String EXTRA_SOME_THING = "CustomActivity.EXTRA_SOMETHING";

    public static Intent newIntent(Context context, int arg1) {
        Intent intent = new Intent(context, CustomActivity.class);
        intent.putExtra(EXTRA_SOME_THING arg1);
        return intent;
    }

    //... other methods
}

我希望该库的用户能够扩展此活动:

package com.example.android.myproject;

public class MyCustomActivity extends CustomActivity {
    //... some methods
}

但我希望用户能够依赖我的公共工厂newInstance()

// start MyCustomActivity
int someInt = 0;
Intent intent = MyCustomActivity.newIntent(getApplicationContext(), someInt);
startActivity(intent);

但是,当我尝试以这种方式启动活动时,出现错误:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.android.myproject/com.example.android.somelibrary.CustomActivity}; have you declared this activity in your AndroidManifest.xml?

我在各自的清单中声明了这两个活动:SomeLibrary清单中的CustomActivity和MyProject清单中的MyCustomActivity。

我很困惑,因为如果我更改启动活动调用,一切都会正常进行:

Intent intent = new Intent(context, MyCustomActivity.class);
startActivity(intent);

这使我认为我已经在MyProject正确设置了所有模块依赖项。 这仅仅是Java的限制吗? 我不能以这种方式调用静态方法(在子级上调用父方法)吗?

这行不通。

CustomActivity.newIntent()是在CustomActivity类上定义的静态方法。 该静态方法返回一个指向CustomActivity.class的Intent。

因此,当您调用MyCustomActivity.newIntent()时,会得到什么? 指向CustomActivity.class的意图。 因为这就是CustomActivity中定义的方法。 触发该意图将不起作用,因为在应用的清单中未定义CustomActivity。 无论如何,这并不重要,因为您要启动MyCustomActivity,而不是CustomActivity。

您想要的是一个静态方法,它“知道”将调用哪个类名。 不幸的是,这在Java中是不可能的。

现在,这么说...我将向您展示如何做到这一点。 不过,我不建议这样做。 (稍后再说为什么)

无论如何,就像我说的那样:静态方法不知道在哪个类上调用它们。 实例方法可以。 因此,您可以这样做:

public class CustomActivity extends Activity {

    private static final String EXTRA_SOME_THING = "CustomActivity.EXTRA_SOMETHING";

    public Intent newIntent(Context context, int arg1) {
        Intent intent = new Intent(context, getClass());
        intent.putExtra(EXTRA_SOME_THING arg1);
        return intent;
    }

    //... other methods
}

同样的事情,但是:

  • 这是一个实例方法,而不是静态方法
  • 我们说的是getClass()(它动态返回当前实例的类),而不是说CustomActivity.class(它总是指向CustomActivity类)。

然后,如果我们使用MyCustomActivity扩展CustomActivity,我们可以创建一个MyCustomActivity意图,如下所示:

Intent i = new MyCustomActivity().newIntent(getActivity(), 1);

它将起作用。

我为什么不建议这样做:

  • 丑陋又怪异。 如果您想做某事并且语言使它变得丑陋和粗糙,则请使用hansolov(“让语言取胜”);
  • 它启用的技术不是一个好主意。

让我继续讲一下。 继承有点像注塑成型的塑料:我们看到这种技术用来制造我们每天依赖的工具,但是如果我们在家做,那很可能会一团糟。

那是因为继承比看起来要难。 如果三个活动都需要使用一种特定类型的参数,那是否意味着它们都应该成为活动的同一种? 可能不是。 我没有足够的空间或时间来学习它(其他人说得比以往任何时候都更好),但是足以说有很多这样共享代码的陷阱。

这是否意味着他们可以通过其他方式共享某些代码? 当然! 将实现放在另一个类中,并使用自己的静态newIntent()方法进行调用。 还有更多代码,但是没有这个陷阱。 因此,我建议改为这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM