我有一个根应用程序,应该在执行过程中的某个时刻捕获屏幕。为了实现这一点,我使用以下代码与 Android shell 进行交互:
private static Process su = Runtime.getRuntime().exec("su");
private static DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
private static DataInputStream inputStream = new DataInputStream(su.getInputStream());
private void CaptureScreen() {
outputStream.writeBytes("/system/bin/screencap -p\n");
outputStream.flush();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//outputStream.writeBytes("echo test\n");
//outputStream.flush();
}
即使我多次调用它,它也能正常工作,但是当我发出一个在 CaptureScreen 调用之间生成 shell 输出的虚拟命令时,BitmapFactory.decodeStream 会失败。考虑到这一点,我有几个问题:
- 我认为发生这种情况是因为 InputStream 中的数据没有 不再纯粹与图像数据相关。由于运行时是单一的 实例(如 here ),我再次假设其他 进程还可以在我的 InputStream 中引入它们的输出 直播系统。我如何确保只从以下位置获取我需要的数据 输入流?
- 为什么多次调用 CaptureScreen 后仍能正常工作?如何 BitmapFactory.decodeStream 是否设法从 输入流?成功后是否会“消耗”相关数据?做 它从输入流中搜索最后一个图像数据?如果是这样,为什么会这样 当图像数据之前有不相关数据时失败 输入流?
我知道我可以通过将图像写入文件然后从那里读取它来解决这个问题,但我想避免 I/O 操作以提高性能。
最佳答案
经过一段时间的研究,我找到了自己问题的答案:
- 虽然运行时是单实例,但在其上执行代码会自行启动一个新进程。与此进程相关的输入和输出流只能由此进程写入/读取(除非另一个进程专门将其流重定向到此进程,这在我的情况下极不可能)。
- 输入流的内容确实在读取时被“消耗”,因此多次调用此函数会完整地写入/读取图像数据。使用与图像无关的数据“污染”进程的输入流会破坏decodeStream的功能。
另请记住,“su”不是一个结束的命令。在被调用之前它不会终止。这是我在代码中使用的修改后的类:
public class BitmapScreencap {
public final static BitmapScreencap Get = new BitmapScreencap();
private BitmapScreencap() { }
public Bitmap Screen() {
try {
Process process = Runtime.getRuntime().exec("su");
OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream());
outputStream.write("/system/bin/screencap -p\n");
outputStream.flush();
Bitmap screen = BitmapFactory.decodeStream(process.getInputStream());
outputStream.write("exit\n");
outputStream.flush();
outputStream.close();
return screen;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
并且可以从项目中的任何位置调用它,如下所示:
BitmapScreencap.Get.Screen();
关于java - 确保从 InputStream 读取正确的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29395281/