CLOUGH
CLOUGH

Reputation: 741

Executing 'adb logcat' command using Runtime class

I was trying to get the logcat content into a JTextPane. I used following code hoping it will return the content as String but it freeze and also, doesn't produce an error.

Process exec = null;
    try {
        exec = Runtime.getRuntime().exec("adb logcat -d");
        InputStream errorStream = exec.getErrorStream();
        BufferedReader ebr = new BufferedReader(new InputStreamReader(errorStream));
        String errorLine;
        while ((errorLine = ebr.readLine()) != null) {
            System.out.println("[ERROR] :- " + errorLine);
        }

        if (exec.waitFor() == 0) {
            InputStream infoStream = exec.getInputStream();
            InputStreamReader isr = new InputStreamReader(infoStream);
            BufferedReader ibr = new BufferedReader(isr);
            String infoLine;
            while ((infoLine = ibr.readLine()) != null) {
                System.out.println("[INFO] :- " + infoLine);
            }
        }
    } catch (IOException | InterruptedException ex) {
        ex.printStackTrace();
    } finally {
        if (exec != null) {
            exec.destroy();
        }
    }

I referred to some tutorials but, they were not filling my problem. Is this wrong? Are there any other methods to get the logcat content as a String programmatically? Sorry if this is a dumb question.

Upvotes: 1

Views: 3632

Answers (1)

Ryan J
Ryan J

Reputation: 8323

The issue you're seeing is that you're trying to process command streams and wait for the executing process, all in the same thread. It's blocking because the process reading the streams is waiting on the process and you're losing the stream input.

What you'll want to do is implement the function that reads/processes the command output (input stream) in another thread and kick off that thread when you start the process.

Second, you'll probably want to use ProcessBuilder rather than Runtime.exec.

Something like this can be adapted to do what you want:

public class Test {
    public static void main(String[] args) throws Exception {            
        String startDir = System.getProperty("user.dir"); // start in current dir (change if needed)
        ProcessBuilder pb = new ProcessBuilder("adb","logcat","-d");
        pb.directory(new File(startDir));  // start directory
        pb.redirectErrorStream(true); // redirect the error stream to stdout
        Process p = pb.start(); // start the process
        // start a new thread to handle the stream input
        new Thread(new ProcessTestRunnable(p)).start();
        p.waitFor();  // wait if needed
    }

    // mimics stream gobbler, but allows user to process the result
    static class ProcessTestRunnable implements Runnable {
        Process p;
        BufferedReader br;

        ProcessTestRunnable(Process p) {
            this.p = p;
        }

        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader(p.getInputStream());

                br = new BufferedReader(isr);

                String line = null;
                while ((line = br.readLine()) != null)
                {
                    // do something with the output here...                        
                }
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Upvotes: 3

Related Questions