【问题标题】:Static initializer per Activity (just like Fragment)每个 Activity 的静态初始化器(就像 Fragment 一样)
【发布时间】:2015-11-11 01:50:46
【问题描述】:

我们鼓励在传递参数时使用静态初始化器(又名the newInstance() pattern)每个Fragment。如果是Activity,则没有提及。并且每次我们要开始一个活动时,我们必须先创建一个Intent,如下所示:

public class FirstActivity extends Activity {
    ...
    Intent intent = new Intent(this, SecondActivity.class);
    startActivity(intent);
    ...
}

如果我们想要传递一些参数,这会变得更加复杂,因为我们需要为每个参数命名,如下所示:

public class FirstActivity extends Activity {
    ...
    int age = 10;
    int count = 20;
    String message = "hello";

    Intent intent = new Intent(this, SecondActivity.class);
    intent.putExtra("Age", age);
    intent.putExtra("Count", count);
    intent.putExtra("Message", message);
    startActivity(intent);
    ...
}

在 SecondActivity 中,我们应该检索这些具有相同名称的参数:

public class SecondActivity extends Activity {
    ...
    int mAge;
    int mCount;
    String mMessage;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        mAge = getIntent().getIntExtra("Age", 0);
        mCount = getIntent().getIntExtra("Count", 0);
        mMessage = getIntent().getStringExtra("Message");
    }
    ...
}

此外,我们使用的这些名称,“Age”、“Count”和“Message”是硬编码且容易出错的。大多数情况下,我们使用一个辅助类,称为 IntentExtraKeys,并使用该类中的名称,如下所示:

public class IntentExtraKeys{

    public static final String AGE_KEY = "age_key";
    public static final String COUNT_KEY = "count_key";
    public static final String MESSAGE_KEY = "message_key";
}

在活动中:

public class FirstActivity extends Activity{

    ...
    intent.putExtra(IntentExtraKeys.AGE_KEY, age);
    ...
}

public class SecondActivity extends Activity{

    ...
    mAge = getIntent().getIntExtra(IntentExtraKeys.AGE_KEY, 0);
    ...
}

除此之外,我们可以有如下内容:

public class FirstActivity extends Activity{

    ....
    SecondActivity.startActivity(this, age, count, message);
    ...
}

public class SecondActivity extends Activity{
    ...
    private static final String AGE_KEY = "age_key";
    private static final String COUNT_KEY = "count_key";
    private static final String MESSAGE_KEY = "message_key";

    public static void startActivity(Context context, int age, int count, String message){

    Intent intent = new Intent(context, SecondActivity.class);
    intent.putExtra(AGE_KEY, age);
    intent.putExtra(COUNT_KEY, count);
    intent.putExtra(MESSAGE_KEY, message);
    context.startActivity(intent); 
    }
    ...
}

这样,每次我们想要启动活动时,我们就不用编写代码来创建Intent,如果我们要传递一些参数,我们不需要给它们命名。只有我们开始的活动知道他们的名字,而且看起来更干净,就像在fragments 中一样。

这是糟糕的设计吗?为什么这不常见?

【问题讨论】:

  • 我实际上是为很多活动、服务,尤其是意图服务这样做的。对于内部操作,我认为这种模式没有任何问题。如果使用隐式意图等,可能不会使用它。

标签: android android-activity static-methods


【解决方案1】:

在片段中使用静态初始化模式,因为即使您第一次自己实例化片段,默认构造函数必须存在,以便平台可以在重新构建活动时自行再次实例化它由于配置更改。

另一方面,Activity 总是由系统实例化,它们必须不需要任何特殊的工厂方法或构造函数来保持它们作为 Intent 导出以供其他应用程序和系统本身使用的能力;这就是为什么静态初始化器对活动没有太大意义的原因。虽然它们非常有效,您可以根据需要使用它们,但它们可能会使为以各种略有不同的方式执行相同功能的活动自定义初始化代码变得复杂,并且它们会产生错误的耦合感。

【讨论】:

  • “以各种略有不同的方式执行相同的功能,它们会产生一种错误的耦合感。”能详细点吗?
  • 当然。想象一下具有不同操作模式和配置选项的选择器或图库活动 - 您必须为不同的操作模式(这本身很好)制定不同的重载,您无法共享给其他应用程序并且除了配置之外不能做任何其他事情并返回/启动一个意图,否则您可能会将您的活动构造耦合到这些方法,从而打破与平台的隐式合同,即唯一的构造路径必须是默认构造函数。
【解决方案2】:

对于片段

使用静态函数创建 Fragment 有一些原因

  1. 使用单点创建 Fragment 实例。这确保了多片段初始化具有相同的输入参数处理等。

  2. 帮助开发者避免创建非静态嵌套片段。片段和活动必须解耦。

  3. 可以多次调用实用程序函数。例如:Fragment 正在 TabLayout、ViewPager 中使用。

对于活动

您可以像以前一样创建实用程序。没问题。很难说它是糟糕的代码还是不常见的代码。

如果你将使用函数 More than one 或者 Activity 有输入参数。您可以像以前一样创建 Utility 函数。

【讨论】:

  • 我喜欢你强调它无论如何都不是反模式,而是通过集中初始化完全相反。但它确实有缺点,因为我正在与 cmets 中的 OP 讨论我的答案。
猜你喜欢
  • 2021-12-14
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多