Android Studio使用ScriptEngine开发计算器点击等号崩溃如何解决
安卓计算器ScriptEngine崩溃修复方案
核心崩溃原因
- 安卓7.0以上系统官方移除了内置的JavaScript脚本引擎,调用
new ScriptEngineManager().getEngineByName("JavaScript")会返回null,后续调用eval方法直接触发空指针异常,这是崩溃的最主要原因。 - 现有代码仅捕获了
ScriptException,未覆盖空指针、返回值为null时调用toString、非法表达式等其他异常场景。 - 输入为空、仅输入运算符等边界场景未做校验,也会触发运算异常。
修复方案
方案1:替换为轻量表达式计算库(推荐,稳定性更高)
使用专门的数学表达式计算库exp4j,不需要依赖系统ScriptEngine,兼容性更强:
- 在build.gradle中引入依赖:
dependencies { implementation 'net.objecthunter:exp4j:0.4.8' }
- 替换等于按钮的点击逻辑:
but19.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view){ String r_text = tview.getText().toString().trim(); // 空输入直接返回 if (r_text.isEmpty()) { return; } // 替换运算符 r_text = r_text.replace("×", "*").replace("÷", "/"); String result = ""; try { Expression expression = new ExpressionBuilder(r_text).build(); double res = expression.evaluate(); // 处理整数和小数显示逻辑 if (res % 1 == 0) { result = String.valueOf((long) res); } else { result = String.valueOf(res); } } catch (Exception e) { // 所有异常统一捕获,避免崩溃 result = "输入错误"; } tview.setText(result); } });
方案2:补全现有代码的异常与空判断(如果坚持用ScriptEngine)
如果不想引入第三方库,需要先引入兼容的ScriptEngine依赖,同时补全所有空判断和异常捕获:
but19.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view){ String r_text = tview.getText().toString().trim(); if (r_text.isEmpty()) { return; } r_text = r_text.replace("×", "*").replace("÷", "/"); String result = ""; ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); // 先判断引擎是否初始化成功 if (engine == null) { tview.setText("引擎初始化失败"); return; } try{ Object ff = engine.eval(r_text); if (ff != null) { result = ff.toString(); } } catch (Exception e) { // 捕获所有异常,不要只抓ScriptException result = "输入错误"; } if (!result.isEmpty()){ tview.setText(result); } } });
注:如果使用该方案,需要额外引入第三方JavaScript引擎依赖到项目中,否则系统高版本还是会返回null引擎。
内容的提问来源于stack exchange,提问作者Rahasyar Desh
相关产品推荐
相关产品推荐

