今天刚好在整理代码,发现代码里面居然有中文硬编码,这可把我急坏了,同事这编码水平堪忧呀
算了,还是自己动手改改吧,把中文和英文字符串分别定义在相应目录下的 strings.xml,然后打算用Context去访问
刚开始我是这么写的:
Context mContext = InstrumentationRegistry.getContext();
String portableHotspot = mContext.getString(R.string.portable_hotspot);
结果抛出了异常:
android.content.res.Resources$NotFoundException: String resource ID #0x7f0b0024
at android.content.res.Resources.getText(Resources.java:410)
at android.content.res.HwResources.getText(HwResources.java:465)
at android.content.res.Resources.getString(Resources.java:504)
at android.content.Context.getString(Context.java:560)
at com.example.termctrl.functions.HotpotControl.<init>(HotpotControl.java:51)
at com.example.termctrl.UiAutoController.testHotpotControl(UiAutoController.java:778)
at java.lang.reflect.Method.invoke(Native Method)
上网查了很久,一直没找到原因,直到发现了这个链接:
https://stackoverflow.com/questions/17713226/accessing-resources-for-android-ui-automator-tests
把Context的使用方法换了下:
Context mContext = InstrumentationRegistry.getTargetContext();
注意,这里使用的是 getTargetContext,点进去稍微看了下源码:
public Context getTargetContext() {
return mAppContext;
}
从返回的名字看,是 app 的 context,嗯,想了下,应该合理,而 getContext 的源码:
public Context getContext() {
return mInstrContext;
}
从名字看,应该是 Instrumentation Context 的缩写,好像不太对,要想访问资源,当然是要访问 Application 的资源,嗯,好像是这么个道理。于是又顺着看了下 mAppContext 是如何赋值的:
final void init(ActivityThread thread,
Context instrContext, Context appContext, ComponentName component,
IInstrumentationWatcher watcher, IUiAutomationConnection
uiAutomationConnection) {
mThread = thread;
mMessageQueue = mThread.getLooper().myQueue();
mInstrContext = instrContext;
mAppContext = appContext;
mComponent = component;
mWatcher = watcher;
mUiAutomationConnection = uiAutomationConnection;
}
是在 init 初始化函数里面赋值的,appContext 是被传过来的参数,应该就是某个应用自己的 Context,比如像 Application Context。
这个问题好像很简单,好像也不简单,第一次使用 UIAutomator 去访问String资源,大家可以延伸到访问其他资源,特此总结一下。