在安卓中,定义常量的最佳方式是什么?静态类、接口还是XML资源?

104
我正在开发一款Android应用程序,它使用Web服务从服务器获取数据,因此我有三组不同的URL来指向开发系统、测试服务器和生产服务器。每当我想要进行测试或发布应用程序时,更改URL非常困难,所以我计划将其配置化,以便应用程序可以根据我的构建类型配置常量获取相应的URL。
  • 最佳方法是使用哪种常量,Java静态类、Java公共接口还是XML资源文件?什么时候?为什么?
  • 哪种方法提供更好的性能?什么时候?为什么?

例如:XML资源。

<integer name="config_build_type">0</integer>
<string-array name="url_authentication">
    <item >http://development.com/xxxx</item>
    <item >http://test.com/xxx</item>
    <item >http://example.com/xxx</item>
</string-array>

Java 静态常量

public class Config {
    public static final int BUILD_TYPE = 0; // 0 - development, 1 - test, 2 - live
    public static final String[] URL_AUTHENTICATION = {"http://development.com/", "http://test.com/", "http://example.com"};
}

1
我非常怀疑性能会成为一个问题... - Alex Lockwood
Web服务调用是在单个类还是多个类中? - Venky
@venky,在多个类中,每个类都有不同的目的,例如一个用于用户身份验证,另一个用于下载数据等。 - Jayabal
8个回答

98

这两者之间存在很大的区别,即您可以在 XML 布局中引用项目资源。它们在应用程序上下文中可用,因此可以在整个全局应用程序中访问。使用项目资源的最大优点是易于访问,并且允许您显著组织您的项目。

static final 常量编译进 Java 字节码中;项目资源编译成二进制格式并打包到 apk 文件中。访问任一资源都非常高效... 如果两者之间有差异,则最多是微不足道的。

对于如何在项目中使用资源/常量,没有固定的规则。也就是说,我个人使用资源作为可能需要在我的 XML 或 Java 代码中使用的值。另一方面,我通常使用 static final 常量作为仅将由我的 Java 代码使用并且特定于我的实现的值。

另外请注意,可以根据设备的当前配置(例如屏幕大小、语言环境等)在运行时加载 XML 资源。因此,在决定是否在 XML 中声明常量或直接在 .java 文件中声明常量时,应考虑这一点。


资源在不同的版本/构建类型中配置起来要容易得多。 - HopefullyHelpful
@Alex 我有一个疑问,你能否请解答一下:建议尽量少使用静态变量,那么如果我们创建了带有静态变量的常量文件,会不会影响应用程序的性能? - Pallavi
2
另一个需要考虑的因素是,如果一个最终常量被多个类使用,那么如果该常量发生变化,则所有这些对象都需要重新编译。但如果将常量存储为资源,则不会出现这种情况。对于需要长时间编译的大型项目来说,这可能是一个重要的考虑因素。 - orodbhen

29

对于那些想要了解如何使用类来定义常量并在需要时调用的人。

Constant.java

    package org.nrum.nrum;

/**
 * Created by rajdhami on 5/23/2017.
 */
public class Constant {
    public static final String SERVER = "http://192.168.0.100/bs.dev/nrum";
//    public static final String SERVER = "http://192.168.100.2/bs.dev/nrum";
    public static final String API_END = SERVER + "/dataProvider";
    public static final String NEWS_API = API_END + "/newsApi";
    public static final String BANNER_API = API_END + "/bannerApi/lists";
    public static final String NOTICE_API = API_END + "/noticeApi/lists";
    public static final String UPLOAD_PATH = SERVER + "/uploads";
    public static final String UPLOAD_PATH_BANNER = UPLOAD_PATH + "/company_1/banner";
    public static final String UPLOAD_PATH_NEWS = UPLOAD_PATH + "/company_1/news";
    public static final int BANNER_TRANSITION_DURATION = 5000;
    public static final int NOTICE_BUTTON_BLINK_DURATION = 5000;
    public static final int BANNER_FETCH_LIMIT = 3;
}

现在我们可以以下面的方式使用上述常量。

Constant.NOTICE_BUTTON_BLINK_DURATION

2
问题是关于最佳方式的! - shadygoneinsane
@Umar 我想要使用不同的角色和不同的URL,请帮忙,之前我一直使用和你一样的。 - Kuldeep Singh

13

通常情况下:

  • 相比于Java文件中的常量,XML值在布局文件和清单文件中的可访问性更高
  • 相比于Java文件中的常量,XML值具有更好的多语言支持优势

1
谢谢Dheeresh,是的,我明白了,在xml中保持配置对于布局、清单和Java都很有用。 - Jayabal

2

这个问题是关于仅供Java代码内部使用的常量。这是一个不同的情况。对于属于用户界面的文本标签的特定情况,正如您所提到的,毫无疑问的是正确的位置是Android项目的XML资源。 - cesargastonec

2

我认为这两种方法都不错,但取决于您的要求。

如果您的值(Web服务链接)在XML中,并且假设这些值(Web服务链接)发生了任何变化,您只需在XML文件中轻松更改即可。

但是,如果您将其用作静态变量放在类内部,您必须在所有类文件中进行更改。

因此,我的建议是将常量从源文件中分离出来并放入资源中以进行访问。


1
你可以很容易地在XML文件中进行更改。这与在Java文件中进行更改一样简单,在两种情况下,您都需要重新构建项目,因此我认为这没有区别,更不用说优势了。 - Fran Marzoa

0
项目资源需要访问Context,但在静态方法中除非您将其传递进去,否则无法获得Context。但在Activity中始终可用 - 资源和布局之间似乎存在着优先关系。
对于可能在静态方法中处理的应用程序变量和常量,我创建了一个抽象类,并在所有其他项目类文件中进行静态导入(此常量类)。

0

如果常量与语言环境相关或在清单中使用,您可以考虑使用XML值

如果常量与翻译或语言环境无关,也不在清单中使用,我会避免将其放入XML资源中

我会在ViewModel或需要使用常量作为键的任何其他地方添加枚举。

enum class Key{
        key,rule,practice
    }

或者

const val MY_CONST = "my constant"

0

In Kotlin:

class Foo() { 
    // any other code for the class Foo 

    companion object {
        const val MY_CONSTANT = "my constant"
    }
} 

这种方法特别适用于数据对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接