You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用调用startActivity()崩溃:无法暂停Activity问题求助

Android调用startActivity时崩溃:unable to pause activity问题解决

问题现象

调用startActivity()启动新页面时应用崩溃,系统抛出错误提示:unable to pause activity

错误日志(翻译后)

I/View: 按键抬起事件分发给androidx.appcompat.widget.AppCompatEditText{6ecc362 VFED..CL. .F...... -4,137-487,212 #7f08016e app:id/scanPrompt}, 事件 = KeyEvent { action=ACTION_UP, keyCode=KEYCODE_KEY_RSCAN, scanCode=114, metaState=0, flags=0x8, repeatCount=0, eventTime=2665409, downTime=2664922, deviceId=7, source=0x101 }
D/OpenGLRenderer: 缓存纹理3上传:x, y, 宽高 = 16, 0, 129, 505
D/AndroidRuntime: 正在关闭VM
E/AndroidRuntime: 致命异常:main
    进程:com.example.smacstockroom, PID: 5680
    java.lang.RuntimeException: 无法暂停活动 {com.example.smacstockroom/com.example.smacstockroom.Products}: java.lang.IllegalArgumentException: 接收器未注册:com.example.smacstockroom.Products$1@750f15b
        at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3835)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3794)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3768)
        at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3742)
        at android.app.ActivityThread.-wrap16(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1539)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:203)
        at android.app.ActivityThread.main(ActivityThread.java:6251)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
     引起原因:java.lang.IllegalArgumentException: 接收器未注册:com.example.smacstockroom.Products$1@750f15b
        at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:1012)
        at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1342)
        at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:608)
        at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:608)
        at com.example.smacstockroom.Products.onPause(Products.java:172)
        at android.app.Activity.performPause(Activity.java:6806)
        at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1322)
        at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3817)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3794)
        at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3768)
        at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3742)
        at android.app.ActivityThread.-wrap16(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1539)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:203)
        at android.app.ActivityThread.main(ActivityThread.java:6251)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

业务实现代码

if((TypeMov).equals("IN") || (TypeMov).equals("INRW")) {
    String query="SELECT *  FROM prods_locations pl inner join inventory inv on inv.pn=pl.pn   where pl.pn = '"+productcode+"' and pl.location='"+locationid+"';";
    Statement statement = connection.createStatement();
    ResultSet result = statement.executeQuery(query);
    if (result.next()) {
        Intent newScreen = new Intent(Products.this, MovtoProducts.class);
        String stockprod= result.getString("inv.stockqty");
        String inputsprod= result.getString("inv.incomeqty");
        String outputsprod= result.getString("inv.outgoingqty");
        String locastock= result.getString("pl.stockqty");
        String locainputs= result.getString("pl.incomes");
        String locaoutputs= result.getString("pl.outgoings");
        newScreen.putExtra("productid", productcode);
        newScreen.putExtra("proddesc", result.getString("title"));
        newScreen.putExtra("proddetail", result.getString("detail"));
        newScreen.putExtra("location", locationid);
        newScreen.putExtra("Typemov", TypeMov);
        newScreen.putExtra("stock", stockprod);
        newScreen.putExtra("inputs", inputsprod);
        newScreen.putExtra("outputs", outputsprod);
        newScreen.putExtra("locstock", locastock);
        newScreen.putExtra("locinputs", locainputs);
        newScreen.putExtra("locoutputs", locaoutputs);
        newScreen.putExtra("HostIp", getIntent().getStringExtra("HostIp"));
        newScreen.putExtra("user", getIntent().getStringExtra("User"));
        newScreen.putExtra("psw", getIntent().getStringExtra("Pwd"));
        connection.close();

        startActivity(newScreen);
        finish();
        // activitylancher.launch(newScreen);
    } else{
        Toast errorToast = Toast.makeText(getApplicationContext(), "Product not found at location ",
        Toast.LENGTH_SHORT);
        errorToast.show();
    }

解决方案

核心问题定位

崩溃的直接原因是Products类的onPause方法(第172行)尝试注销一个未注册的广播接收器。Android系统不允许注销未注册的接收器,否则会抛出IllegalArgumentException,进而导致Activity暂停失败,引发崩溃。

修复步骤

  1. 管理广播接收器的注册状态

    • 将广播接收器实例改为类成员变量,避免使用匿名内部类直接在registerReceiver中创建
    • 添加一个布尔变量(如isReceiverRegistered)标记接收器是否已注册
    • 在onResume/onCreate中注册接收器时,将isReceiverRegistered设为true
    • 在onPause中注销前,先判断isReceiverRegistered是否为true,仅当已注册时才执行注销,并将标记设为false

    示例代码:

    private BroadcastReceiver mReceiver;
    private boolean isReceiverRegistered = false;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化接收器
        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 处理广播逻辑
            }
        };
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        if (!isReceiverRegistered) {
            registerReceiver(mReceiver, new IntentFilter("YOUR_ACTION"));
            isReceiverRegistered = true;
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (isReceiverRegistered) {
            unregisterReceiver(mReceiver);
            isReceiverRegistered = false;
        }
    }
    
  2. 额外优化:修复SQL注入风险
    当前业务代码中直接拼接SQL语句,存在严重的SQL注入漏洞。建议改用PreparedStatement参数化查询:

    String query = "SELECT * FROM prods_locations pl inner join inventory inv on inv.pn=pl.pn where pl.pn = ? and pl.location=?;";
    PreparedStatement statement = connection.prepareStatement(query);
    statement.setString(1, productcode);
    statement.setString(2, locationid);
    ResultSet result = statement.executeQuery();
    

内容的提问来源于stack exchange,提问作者fernando sandoval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:25:57