Properties文件,每一行前面表示Key 中间使用=或者: 分割 后面表示value
在集成 百度TTS语音合成的时候发现Properties居然还可以这么用,以后再写三方的appid appKey 啥的就太舒服了,再也不用写一些常量类了。
接下来看看人家百度是怎么妙用的?
如何获取这些appId appKey applicationId啥的呢?
public class Auth {
private static volatile Auth ourInstance;
private String appId;
private String appKey;
private String secretKey;
private String sn; // 收费纯离线版本需要序列号,离在线版本不需要
private Auth(Context context) {
Properties prop = load(context);
String applicationId = getProperty(prop, "applicationId");
if (!context.getPackageName().equals(applicationId)) {
throw new AuthCheckException("包名不一致,请在app/build.gradle 里 修改defaultConfig.applicationId。\n\n"
+ "auth.properties里写的包名是:'" + applicationId
+ "' ; 实际app的包名是:'" + context.getPackageName() + "'");
}
appId = getProperty(prop, "appId");
appKey = getProperty(prop, "appKey");
secretKey = getProperty(prop, "secretKey");
sn = prop.getProperty("sn"); // 收费纯离线版本需要序列号,离在线版本不需要
}
public static Auth getInstance(Context context) {
if (ourInstance == null) {
synchronized (Auth.class) {
ourInstance = new Auth(context);
}
}
return ourInstance;
}
public String getAppId() {
return appId;
}
public String getAppKey() {
return appKey;
}
public String getSecretKey() {
return secretKey;
}
public String getSn() {
return sn;
}
public boolean hasSn() {
return sn != null;
}
private String getProperty(Properties properties, String key) {
String value = properties.getProperty(key);
if (value == null) {
throw new AuthCheckException("在 assets/auth.properties里没有设置 " + key);
}
return value.trim();
}
private Properties load(Context context) {
try {
InputStream is = context.getAssets().open("auth.properties");
Properties prop = new Properties();
prop.load(is);
is.close();
return prop;
} catch (IOException e) {
e.printStackTrace();
throw new AuthCheckException(e);
}
}
public static class AuthCheckException extends RuntimeException {
public AuthCheckException(String message) {
super(message);
}
public AuthCheckException(Throwable cause) {
super(cause);
}
}
}
在需要使用的地方
没错,这样就搞定了???? !!!!!
我们可能要问了,这个Properties究竟是什么这么神奇,通过key value 就能取到这些参数的值?
//原来Properties就是Hash表,只不过是HashTable
public class Properties extends Hashtable<Object,Object> {
//所以应该好奇的是怎么读取到这些字段的呢?
public synchronized void load(InputStream inStream) throws IOException {
//重点是这个方法,会去解析key value然后存起来
load0(new LineReader(inStream));
}
}
// 读取 auth.properties每一行文本
// 开始读取的字符串作为key 直到遇到空格,: = 开始读取value
// 从key之后的位置+1 读取value
// 存取
private void load0 (LineReader lr) throws IOException {
char[] convtBuf = new char[1024];
int limit;
int keyLen;
int valueStart;
char c;
boolean hasSep;
boolean precedingBackslash;
while ((limit = lr.readLine()) >= 0) {
c = 0;
keyLen = 0;
valueStart = limit;
hasSep = false;
//System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
precedingBackslash = false;
while (keyLen < limit) {
c = lr.lineBuf[keyLen];
//need check if escaped.
if ((c == '=' || c == ':') && !precedingBackslash) {
valueStart = keyLen + 1;
hasSep = true;
break;
}
// Android-changed: use of Character.isWhitespace(c) b/25998006
else if (Character.isWhitespace(c) && !precedingBackslash) {
valueStart = keyLen + 1;
break;
}
if (c == '\\') {
precedingBackslash = !precedingBackslash;
} else {
precedingBackslash = false;
}
keyLen++;
}
while (valueStart < limit) {
c = lr.lineBuf[valueStart];
// Android-changed: use of Character.isWhitespace(c) b/25998006
if (!Character.isWhitespace(c)) {
if (!hasSep && (c == '=' || c == ':')) {
hasSep = true;
} else {
break;
}
}
valueStart++;
}
String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
put(key, value);
}
}