我正在开发一个Android应用程序,我可能需要更改几个变量,而不想重新编译并将android应用程序部署到Android智能手机中。
在java中,我会做一个类似于以下我在java中完成的属性加载器:
public class PropertyLoader {
private static Properties props = null;
/**
* Method initializes the PropertyLoader by reading all configuration settings
* from the RememberMeServer.conf file.
*/
public static void initializeProperties() {
String propFile = getCatalinaDirectory() + "RememberMeServer.conf";
System.out.println(propFile);
File configFile = new File(propFile);
InputStream inputStream = null;
try {
inputStream = new FileInputStream(configFile);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
props = new Properties();
try {
props.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns a string value from the configuration file.
*
* @param key a string which represents the key of the requested value in the configuration file
* @return the value of the requested key from the property file as a string or null if the
* requested key could not be found.
*/
public static String getStringValue(String key) {
return props == null ? null : props.getProperty(key);
}
/**
* Returns an int value from the configuration file.
*
* @param key a string which represents the key of the requested value in the configuration file
* @return the value of the requested key from the property file as an int or null if the
* requested key could not be found.
*/
public static Integer getIntValue(String key) {
return props == null ? null : Integer.valueOf(props.getProperty(key));
}
/**
* Returns the directory of the project�s workspace as a string
*
* @return Returns the directory of the project�s workspace as a string
*/
public static String getWorkspaceDirectory() {
URL url = PropertyLoader.class.getClassLoader().getResource(
"hibernate.cfg.xml");
return url.getFile().substring(0,
url.getFile().lastIndexOf("hibernate.cfg.xml"));
}
/**
* Returns the directory of the servlet container catalina directory as a string
*
* @return Returns the directory of the servlet container catalina directory as a string
*/
public static String getCatalinaDirectory() {
String workspace = getWorkspaceDirectory();
return workspace
.substring(0, workspace.lastIndexOf("RememberMeServer"));
}
}
虽然在android中有一些叫做SharedPreferences的东西,我已经在我的应用程序中使用了它。虽然我从不使用SharedPreferences直接在文件中更改变量信息,但仅使用应用程序的代码。
Android应用程序中最好的选择是什么?
因为我想要实现的是,更好地用属性加载器代表,它可以保存我不想在我的java代码中硬编码的东西。
答案 0 :(得分:1)
您可以使用xml文件来存储您的配置,访问方式与作为标记的键和作为标记值的值相同。
Path = yourapp / res / xml / RememberMeServer.xml
RememberMeServer.xml
内容 -
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>day</key>
<integer>1</integer>
<key>hour</key>
<integer>12</integer>
<key>minute</key>
<integer>10</integer>
<key>second</key>
<integer>14</integer>
<key>background</key>
<string>Graphic_6_7_Red</string>
<key>Online</key>
<true/>
</dict>
</plist>
然后访问并使用键值 -
班级代码 -
String day, hour, minute, second, background;
boolean status;
int resId = getResources().getIdentifier("xml/" + RememberMeServer,
"string", getActivity().getPackageName());
XmlPullParser xpp0 = getResources().getXml(resId);
XMLData xml = new XMLData(xpp0);
day = (xml.getValue("day"));
hour= (xml.getValue("hour"));
second= (xml.getValue("second"));
minute= (xml.getValue("minute"));
background= (xml.getValue("Graphic_6_7_Red"));
status= (xml.checkFieldPresence("Online"));
类XMLData.java - (此类包含按键访问值的逻辑)
public String getValue(String key) {
int start = this.xmldoc.indexOf("<key>"+ key + "</key>");
if(start == -1)
return "";
String xmldoc2 = this.xmldoc.substring(start);
start = xmldoc2.indexOf("</key>");
xmldoc2 = xmldoc2.substring(start);
xmldoc2 = xmldoc2.substring(6);
start = xmldoc2.indexOf(">");
xmldoc2 = xmldoc2.substring(start + 1);
int end = xmldoc2.indexOf("</");
xmldoc2 = xmldoc2.substring(0, end);
return xmldoc2;
}
public boolean checkFieldPresence(String key)
{
int start = this.xmldoc.indexOf(key + "</key>");
if(start == -1)
return false;
else
return true;
}
注意:
您可以更改文件RememberMeServer.xml
中任意键的任何值。
这提供了您不必担心获取密钥保存值的灵活性。无论值是什么,方法都会通过键返回这些值。
SharedPreferences
也是一件好事,但正如你所说,你有很多变量变化很多,所以最好的解决方案是将它们全部放在xml文件中,并在需要时访问它们。您可以根据要求更改任何值,但仍然是特定于内容的。整个逻辑集中在一个xml文件中,您可以查看和更改单个文件以修改任何值。
答案 1 :(得分:0)
我真的不明白为什么你没有使用正常的应用资源?根据您的描述,这正是您所寻找的。您可以在那里指定所有类型的值,诸如ip和port之类的东西以及其他重要值应始终仍然在资源中。例如,如果你需要某个整数,你可以在 res / values / ints.xml 中定义一个整数:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="some_integer">27</integer>
<integer name="another_integer">42</integer>
</resources>
或者可以在 res / values / strings.xml :
中定义字符串<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="some_string">Some Text</integer>
<string name="another_string">qwerty</integer>
</resources>
您在这些资源中定义的所有值都可以在以后加载:
Resources resources = getResources();
int someInteger = resources.getInteger(R.integer.some_integer);
String someString = resources.getString(R.string.some_string);
您可以在the official documentation中找到有关应用资源的更多信息。
另一种选择当然是SharedPreferences
。在内部,SharedPreferences
会保存到File
。但我想这不是你想要的,因为它仍然需要你对所有初始值进行硬编码。
如果你愿意的话,我也可以像这样拍一些喜欢的东西:
@Resource(id = R.string.some_string)
private String someString;
@Resource(id = R.integer.some_integer)
private int someInteger;
正如您所看到的,它使用反射和注释来加载资源值。可能非常方便,可能正是您正在寻找的。您可以通过调用以下内容从Object
加载所有带注释的值:
ResourceLoader.load(context, object);
这个ResourceLoader
的源代码没什么特别的,但是目前它只支持加载字符串和整数资源,但扩展它应该没问题:
public class ResourceLoader {
// This is the definition of the @Resource annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Resource {
public int id();
}
public static void load(Context context, Object target) {
final Class<?> cls = target.getClass();
// This gets all declared fields, meaning all inherited fields are ignored
final Field[] fields = cls.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
final Class<?> type = field.getType();
// We check if the Annotation is present
if(field.isAnnotationPresent(Resource.class)) {
final Resource annotation = field.getAnnotation(Resource.class);
final int id = annotation.id();
// And if it is present use the id and type of the field to load
// the correct resource
final Object value = loadValue(context, id, type);
try {
// Finally we set the new value to the field
field.set(target, value);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not set resource value to field " + field, e);
}
}
}
}
private static Object loadValue(Context context, int id, Class<?> type) {
final Resources resources = context.getResources();
if(int.class.isAssignableFrom(type) || Integer.class.isAssignableFrom(type)) {
return resources.getInteger(id);
}
if(String.class.isAssignableFrom(type)) {
return resources.getString(id);
}
throw new IllegalStateException("Type \"" + type + "\" is not supported!");
}
}