简体   繁体   English

读取命令输出java.lang.StringIndexOutOfBoundsException时Android App崩溃

[英]Android App crash while reading command output java.lang.StringIndexOutOfBoundsException

I want to run root commands via my Android application which consists of background Service by using function below: 我想通过以下功能通过包含后台服务的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;
    }

and I am calling this function multiple times by creating Threads: 并且我通过创建线程多次调用此函数:

    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();

I want to get output of root commands so I am giving a specified value for read (here it is 128). 我想获取根命令的输出,因此我为读取提供了一个指定的值(这里是128)。 but after a while it gives this error and my service is killed: 但过一会儿出现此错误,我的服务被终止:

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)

Can it be because of more than one threads run at the same time and why I can't handle Exception by try-catch and continue running my Service ? 可能是因为同时运行多个线程,以及为什么我无法通过try-catch处理Exception并继续运行Service的原因?

When you reach end of file EOF InputStream.read(...) will return -1 , you'll have to check for that before constructing the string, before output += new String(buffer, 0, read); 当你到达文件结尾EOF InputStream.read(...)将返回-1 ,你就必须构建字符串前检查,在此之前output += new String(buffer, 0, read);

Doing something like this: 做这样的事情:

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();
    }
}

Should prevent the exception. 应该防止异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM