Search code examples
javaphpbufferedreaderstringbuilderprocessbuilder

App freezing when appending string in bufferedreader while trying to get php output


Im trying to code an app that starts a server using php binary. However when i read the output from the /data/data/com.mycompany.myapp/php using a BufferedReader, my app is freezing while appending output lines in the while statement. How do i fix this?

as.copy("php", new File("/data/data/com.mycompany.myapp"));
Runtime.getRuntime().exec("/system/bin/chmod 744 /data/data/com.mycompany.myapp/php");
new File("/data/data/com.mycompany.myapp/php").setExecutable(true);
new File("/sdcard/PocketMine-MP/PocketMine-MP.phar").setExecutable(true);
Runtime.getRuntime().exec("/system/bin/chmod -R 777 /sdcard/PocketMine-MP");
        
String[] startserver = {"/data/data/com.mycompany.myapp/php","/sdcard/PocketMine-MP/PocketMine-MP.phar","eng"};
final ProcessBuilder processbuilder = new ProcessBuilder(startserver);
processbuilder.directory(new File("/data/data/com.mycompany.myapp"));
processbuilder.environment().put("TMPDIR","/sdcard/PocketMine-MP/tmp");
processbuilder.redirectErrorStream();
        
java.lang.Process process = processbuilder.start();
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8")); 
        
StringBuilder builder = new StringBuilder();
while(br.readLine() != null){
    builder.append(br.readLine()+"\n");
}
t.append(builder);
}catch(Exception e){
    Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}           
}
}

Solution

  • The cause of a process apparently pausing some time after ProcessBuilder.start() is often related to your application not consuming the stdout and stderr streams as they are generated. You can test this quickly by directing them to a file and read from the files after proc.waitFor ends. Add:

    File outf = new File(TEMPDIR, "run.out");
    File errf = new File(TEMPDIR, "run.err");
    pb.redirectOutput(outf);
    pb.redirectError(errf);
    

    If that works, keep using the file redirect or set up a Runnable/Thread to consume both of getInputStream / getErrorStream.