【问题标题】:Android App crash while reading command output java.lang.StringIndexOutOfBoundsExceptionAndroid 应用程序在读取命令输出时崩溃 java.lang.StringIndexOutOfBoundsException
【发布时间】:2017-07-24 21:36:51
【问题描述】:

我想通过我的 Android 应用程序运行 root 命令,该应用程序由后台服务组成,使用以下功能:

    public static String runAsRoot(String cmd) {
        String output = "";
        try {
            Process p = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"});
            DataOutputStream stdin = new DataOutputStream(p.getOutputStream());
            stdin.writeBytes(cmd + "\nexit\n");
            InputStream stdout = p.getInputStream();
            byte[] buffer = new byte[128];
            int read;
            int loopCount = 0;

//read method will wait forever if there is nothing in the stream
//so we need to read it in another way than while((read=stdout.read(buffer))>0)
            while (true) {
                try {
                    loopCount++;
                    read = stdout.read(buffer);
                    output += new String(buffer, 0, read);
                    if (read < 128 || loopCount > 5) {
                        //we have read everything
                        break;
                    }
                }catch (Exception e){

                }
            }

            //Close streams
            stdin.close();
            stdout.close();
            p.destroy();

            Log.e("Command output:", output);
        } catch (Exception e) {
            e.printStackTrace();
            output = "exceptionFound";
        }

        return output;
    }

我通过创建线程多次调用此函数:

    new Thread(new Runnable() {
                        @Override
                        public void run() {

                            try {

//                                if (notOnTop>10){
//                                    runAsRoot("reboot now");
//                                }

                                int isRunning = controlTopApp();
                                if (isRunning == 0) {
                                    Log.d("Control_OnTop", "Attendance notOnTop,bringToFront");
                                    runAsRoot("am start -n berk.can.myapp.anotherapp/.MainActivity");
                                } else if (isRunning == 1) {
                                    Log.d("Control_OnTop", "Attendance");
                                }

                            } catch (Exception e) {
                                Log.e("Runnable App E.", Log.getStackTraceString(e));
                            }

                        }
                    }).start();

我想获得根命令的输出,所以我给出了一个指定的读取值(这里是 128)。但过了一会儿它给出了这个错误并且我的服务被杀死了:

02-28 16:34:41.751 22377-22759/? W/System.err: java.lang.StringIndexOutOfBoundsException: length=128; regionStart=0; regionLength=-1
02-28 16:34:41.760 22377-22759/? W/System.err:     at java.lang.String.failedBoundsCheck(String.java:508)
02-28 16:34:41.760 22377-22759/? W/System.err:     at java.lang.String.<init>(String.java:225)
02-28 16:34:41.760 22377-22759/? W/System.err:     at java.lang.String.<init>(String.java:149)
02-28 16:34:41.760 22377-22759/? W/System.err:     at berk.can.myapp.controllerservice.MyService.runAsRoot(MyService.java:271)
02-28 16:34:41.760 22377-22759/? W/System.err:     at berk.can.myapp.controllerservice.MyService.controlTopApp(MyService.java:176)
02-28 16:34:41.760 22377-22759/? W/System.err:     at berk.can.myapp.controllerservice.MyService.access$000(MyService.java:27)
02-28 16:34:41.760 22377-22759/? W/System.err:     at berk.can.myapp.controllerservice.MyService$TimeTask$1.run(MyService.java:103)
02-28 16:34:41.760 22377-22759/? W/System.err:     at java.lang.Thread.run(Thread.java:818)

可能是因为多个线程同时运行,为什么我无法通过 try-catch 处理异常并继续运行我的服务?

【问题讨论】:

    标签: java android


    【解决方案1】:

    当你到达文件末尾EOFInputStream.read(...) 将返回-1,你必须在构造字符串之前检查它,在output += new String(buffer, 0, read);之前

    做这样的事情:

    while (true) {
        try {
            loopCount++;
            read = stdout.read(buffer);
            if(read == -1){
                break;
            }
            output += new String(buffer, 0, read);
            if (read < 128 || loopCount > 5) {
                //we have read everything
                break;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    

    应该防止异常。

    【讨论】:

    • 那么我的while循环应该是这样的,对吧? : while (true) { try { loopCount++;读取 = 标准输出。读取(缓冲区);如果(读取==-1){中断; } 输出 += 新字符串(缓冲区,0,读取); if (read 5) { //我们已经阅读了所有内容 break; } }catch(异常 e){ } }
    • @BerkCaN 是的,这应该可以防止异常。
    • 非常感谢您,您是救命稻草,请问为什么try-catch无法处理Exception并导致我的服务停止?
    • @BerkCaN 我不确定,我看不到您的导入,但如果您发现 java.lang.Exception 异常,即使发生这种情况,程序也应该继续运行。
    • 现在你说了,我检查了我的代码;即使我使用的是try catch块,代码中也没有'java.lang.Exception'导入,但我认为如果它在java.lang包中我们不需要导入任何东西,不是吗?
    猜你喜欢
    • 2017-11-03
    • 2017-07-01
    • 2015-07-12
    • 2020-03-08
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 2017-06-21
    相关资源
    最近更新 更多