Android方法模拟器运行正常,物理设备崩溃求助(Resource ID异常)
问题描述
selectLexiconForDeletion方法在Android Studio模拟器运行正常,但两台物理设备上崩溃,已排除分辨率问题。崩溃指向builder.show()行,数据库记录已成功读取,报错为Resources$NotFoundException: Resource ID #0x0。
崩溃方法代码
import android.support.v7.app.AlertDialog; public void selectLexiconForDeletion() { // only called from Select options, not when loading databaseAccess = DatabaseAccess.getInstance(this, LexData.getDatabasePath(), LexData.getDatabase()); ArrayList<Structures.Lexicon> lexiconList = databaseAccess.get_lexicons(); if (!lexiconList.isEmpty()) { ArrayList<String> options = new ArrayList<>(); for (int c = 0; c < lexiconList.size(); c++) { options.add(lexiconList.get(c).LexiconName); } final String[] opts; opts = options.toArray(new String[]{}); Log.d("opts", String.valueOf(opts.length)); final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Select"); builder.setItems(opts, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { // opts[item] is the name of the lexicon dialog.dismiss(); deleteLexiconAlert(opts[item]); } }); builder.show(); } }
崩溃日志
android.content.res.Resources$NotFoundException: Resource ID #0x0 at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:216) at android.content.res.Resources.loadXmlResourceParser(Resources.java:2148) at android.content.res.Resources.getLayout(Resources.java:1157) at android.view.LayoutInflater.inflate(LayoutInflater.java:421) at android.view.LayoutInflater.inflate(LayoutInflater.java:374) at android.support.v7.app.AlertController$AlertParams.createListView(AlertController.java:989) at android.support.v7.app.AlertController$AlertParams.apply(AlertController.java:965) at android.support.v7.app.AlertDialog$Builder.create(AlertDialog.java:982) at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:1006) at com.tylerhosting.hoot.hoot.ToolsActivity.selectLexiconForDeletion(ToolsActivity.java:670) at com.tylerhosting.hoot.hoot.ToolsActivity$11.onClick(ToolsActivity.java:426) at android.view.View.performClick(View.java:6892) at android.widget.TextView.performClick(TextView.java:12693) at android.view.View$PerformClick.run(View.java:26104) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
可正常运行的同类方法代码
import android.support.v7.app.AlertDialog; public void selectLexicon() { // only called from Select options, not when loading databaseAccess = DatabaseAccess.getInstance(getActivity().getApplicationContext(), LexData.getDatabasePath(), LexData.getDatabase()); ArrayList<Structures.Lexicon> lexiconList = databaseAccess.get_lexicons(); if (lexiconList.size() > 0) { ArrayList<String> options = new ArrayList<String>(); for (int c = 0; c < lexiconList.size(); c++) { options.add(lexiconList.get(c).LexiconName); } final String[] opts; opts = options.toArray(new String[]{}); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("Select"); builder.setItems(opts, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { // opts[item] is the name of the lexicon dialog.dismiss(); setLexicon(opts[item]); // I THOUGHT setLexicon did this // LexData.setLexicon(getActivity().getApplicationContext(), opts[item]); // Utils.setLexiconPreference(getActivity().getApplicationContext()); } }); builder.show(); SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); Log.i("SetSelectLexiconPrefs", shared.getString("lexicon", "x")); } }
排查与解决方案
对比两个方法的核心差异,问题出在AlertDialog.Builder的上下文参数及关联配置:
替换上下文参数
崩溃方法中使用的this(当前Activity实例)可能存在状态异常(如Activity已进入销毁流程),或主题兼容问题。将代码修改为:final AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());若方法位于Fragment中,则使用
getActivity()确保上下文为活跃的关联Activity实例。检查Activity主题配置
android.support.v7.app.AlertDialog依赖AppCompat主题,需确保当前Activity(ToolsActivity)的主题继承自Theme.AppCompat系列。在AndroidManifest.xml中验证:android:theme="@style/Theme.AppCompat.Light.DarkActionBar"避免使用非AppCompat原生主题。
清理并重建项目
执行Build -> Clean Project清理缓存,再重新构建项目,排除资源编译不完整导致的缺失问题。验证上下文有效性
确保调用selectLexiconForDeletion时,当前Activity处于活跃状态(未调用onDestroy()),避免使用已失效的Activity上下文。
内容的提问来源于stack exchange,提问作者Dana Bell
相关产品推荐
相关产品推荐

