国际化开发,资源配置不完整报错 Resources$NotFoundException

Android 2.3.3
Eclipse Version: 3.7.0
LogCat

LogCat 报错信息:

02-08 10:29:00.171: WARN/dalvikvm(825): threadid=1: thread exiting with uncaught exception (group=0x40025560)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): FATAL EXCEPTION: main
02-08 10:29:00.221: ERROR/AndroidRuntime(825): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.taobao.nokia/com.taobao.nokia.manage.Preference}: 

android.content.res.Resources$NotFoundException: String resource ID #0x7f070088
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.os.Handler.dispatchMessage(Handler.java:99)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.os.Looper.loop(Looper.java:123)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at java.lang.reflect.Method.invokeNative(Native Method)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at java.lang.reflect.Method.invoke(Method.java:507)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at dalvik.system.NativeStart.main(Native Method)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f070088
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.content.res.Resources.getText(Resources.java:201)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.content.res.Resources.getString(Resources.java:254)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.content.Context.getString(Context.java:183)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at com.taobao.nokia.manage.Preference.getDeviceid(Preference.java:384)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at com.taobao.nokia.manage.Preference.setSummary(Preference.java:150)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at com.taobao.nokia.manage.Preference.onCreate(Preference.java:88)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
02-08 10:29:00.221: ERROR/AndroidRuntime(825): ... 11 more


主要错误:

02-08 10:29:00.221: ERROR/AndroidRuntime(825): Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f070088


发生错误原因分析:

Activity部分源代码:

	public String getDeviceid() {
		String setting = sharedPref.getString(Preference.KEY_deviceid,
				context.getString(R.string.def_deviceid));
		return setting;
	}


Eclispe并未提示R.string.def_deviceid存在“def_deviceid cannot be resolved or is not a field”问题;

经查找,发现:因为支持国际化,在res下设置了中文和英文两套资源文件,中文资源为默认资源。

英文资源中已有

<string name="def_deviceid">nokia</string>


而中文资源中没有相应配置。

Android虚拟机设置为默认中文,因此运行应用时找不到相应资源而报错。

 

解决办法:在中文资源中添加相应配置。

Process crashed before executing the test(s): android.content.res.Resources$NotFoundException: String resource ID #0x0 at android.content.res.Resources.getText(Resources.java:466) at android.content.res.Resources.getString(Resources.java:559) at android.content.Context.getString(Context.java:946) at androidx.startup.AppInitializer.discoverAndInitialize(AppInitializer.java:217) at androidx.startup.AppInitializer.discoverAndInitialize(AppInitializer.java:207) at androidx.startup.InitializationProvider.onCreate(InitializationProvider.java:49) at android.content.ContentProvider.attachInfo(ContentProvider.java:2644) at android.content.ContentProvider.attachInfo(ContentProvider.java:2613) at android.app.ActivityThread.installProvider(ActivityThread.java:8292) at android.app.ActivityThread.installContentProviders(ActivityThread.java:7807) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7488) at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2416) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loopOnce(Looper.java:232) at android.os.Looper.loop(Looper.java:317) at android.app.ActivityThread.main(ActivityThread.java:8705) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:913) INSTRUMENTATION_RESULT: shortMsg=Process crashed. INSTRUMENTATION_CODE: 0
07-30
<think>我们正在处理一个Android开发中的异常:Resources$NotFoundException,具体是StringresourceID#0x0。这意味着系统尝试通过资源ID加载字符串,但传入的资源ID为0(无效ID),导致找到资源。根据经验,这个异常通常发生在以下情况:1.在需要字符串资源的地方(如`TextView.setText(intresId)`)传入了一个整数值,但该整数值为0,而0是有效的资源ID。2.可能是在解析数据时,将返回的整数值直接作为资源ID使用,而该值可能为0(例如,从服务器获取的数据中有一个整数字段,本意是要映射到字符串资源,但值为0)。常见的错误代码示例:```javainterrorCode=0;//假设从某个地方获取到的错误码为0textView.setText(errorCode);//这里会抛出异常,因为setText(intresId)期待一个有效的资源ID,而0无效```解决方案:1.**检查传入setText的值**:确保传入`setText`的整数值是一个有效的字符串资源ID(非0)。如果该值可能为0,则应该先判断,然后使用其他方式设置文本(例如设置一个默认字符串)。2.**使用setText的重载方法**:对于整数值,如果它是资源ID,应该将其转换为字符串再设置。例如:`textView.setText(String.valueOf(errorCode))`。3.**检查数据来源**:如果这个整数值来自网络请求或数据库,确保在显示之前进行验证。如果值为0,则按业务逻辑处理(比如显示空字符串或默认提示)。修正后的代码示例:```javainterrorCode=getErrorCode();//假设这个方法返回一个整数,可能为0//错误做法:textView.setText(errorCode);//当errorCode为0时会抛出异常//正确做法:if(errorCode!=0){textView.setText(errorCode);//使用资源ID}else{textView.setText("");//或者设置一个默认文本,如"Unknownerror"}//或者,如果这个整数是资源ID,而是直接要显示的数字,则应该:textView.setText(String.valueOf(errorCode));```另外,注意资源ID为0x0(即0)在Android中永远是一个有效的资源ID,因为有效的资源ID都是非零的。如果问题发生在其他需要资源ID的地方(如设置图片资源等),同样需要检查传入的资源ID是否为0。**引用说明**:上述解决方案基于Android开发中常见的错误处理模式。在Android官方文档中,对于`TextView.setText(intresId)`方法,明确要求`resId`必须是一个有效的资源标识符(非0)[^1]。同时,StackOverflow上也有大量类似问题的讨论[^2]。[^1]:AndroidDeveloperDocumentation:TextView.setText(int)[^2]:StackOverflow:Resources$NotFoundException:StringresourceID#0x0§§相关问题§§1.在Android中,如何避免常见的资源找到异常(Resources$NotFoundException)?2.除了字符串资源,还有哪些情况会导致Resources$NotFoundException?3.如何正确使用Android的资源ID?</think>### AndroidResources$NotFoundException: String resource ID #0x0 解决方案 这个异常通常发生在尝试使用无效的资源ID(0x0)加载字符串资源时。根本原因是**将整数值直接传递给需要资源ID的方法**(如`setText(int)`),而Android框架会尝试将整数值解释为资源ID。当值为0时,系统找到对应的字符串资源。 #### 常见错误场景与修复方案 1. **错误传递整数值给`setText()`** ```java // 错误示例:直接将整数值传递给setText() int count = 0; textView.setText(count); // 抛出Resources$NotFoundException ``` **修复方案**:显式转换为字符串 ```java textView.setText(String.valueOf(count)); // ✅ 正确方式 ``` 2. **API返回整数值处理当** ```java // 错误示例:网络请求返回的整数值直接使用 api.getUserCount().enqueue(response -> { textView.setText(response.body().count); // 风险点 }); ``` **修复方案**:添加空值检查和转换 ```java if (response.body() != null) { textView.setText(String.valueOf(response.body().count)); // ✅ } ``` 3. **自定义Adapter中数据处理错误** ```java // 错误示例:在RecyclerView Adapter中 public void onBindViewHolder(ViewHolder holder, int position) { int itemId = dataList.get(position).getId(); holder.idView.setText(itemId); // ❌ 危险操作 } ``` **修复方案**:强制类型转换 ```java holder.idView.setText(String.valueOf(itemId)); // ✅ ``` 4. **使用`Resources.getText()`时未验证ID** ```java // 错误示例:直接使用可能为0的ID String text = getResources().getText(possibleZeroId); ``` **修复方案**:添加ID有效性检查 ```java if (possibleZeroId != 0) { String text = getResources().getText(possibleZeroId); } else { // 处理无效ID情况 } ``` #### 根本原因分析 - Android资源ID系统从1开始分配,**0x0始终是无效ID**。 - `setText(int resId)`方法要求有效的资源ID,传递普通整数会触发资源查找。 - 异常堆栈会明确显示调用位置: ``` android.content.res.Resources$NotFoundException: String resource ID #0x0 at android.content.res.Resources.getText(Resources.java:367) at android.widget.TextView.setText(TextView.java:6423) // 定位错误行 ``` #### 高级调试技巧 1. **使用Lint检查**: 在Android Studio中运行`Analyze > Inspect Code`,会标记潜在的类型匹配问题: > "Expected resource of type string" 2. **字节码验证**: 通过APK反编译工具(如jadx)检查字节码,确认是否调用了正确的重载方法: ```smali # 错误调用 invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(I)V # 正确调用 invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V ``` 3. **Proguard混淆时的特殊处理**: 如果异常发生在混淆后,确保proguard规则保留资源访问方法: ```proguard -keepclassmembers class **.R$string { public static <fields>; } ``` #### 预防措施 ```mermaid graph TD A[传递值到setText] --> B{值是整数?} B -->|是| C[使用String.valueOf转换] B -->|否| D[直接使用] C --> E[调用setText CharSequence重载] D --> F[检查资源ID有效性] ``` **最佳实践**:始终使用`setText(CharSequence)`重载方法处理动态内容,仅在显示静态资源时使用`setText(int resId)`。 [^1]: Android TextView源码验证资源ID有效性逻辑:`setTextInternal()`方法会验证非0资源ID [^2]: Android资源管理系统设计规范:资源ID 0x0始终表示无效资源
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值