【发布时间】:2014-05-29 15:29:11
【问题描述】:
在我的应用程序中,我创建了一个进程,用于将从 logcat 提取的日志文件记录到 Android 设备中。为此,我使用了一个 Process,它只执行具有 su 权限的 logcat -f log,并保留对此过程的引用以让用户取消日志。
问题是:在我的 Android 版本 (4.1) 中,当我尝试调用 process.destroy() 时出现此异常
I/System ( 2948): Failed to destroy process 3134
D/dalvikvm( 2221): GC_CONCURRENT freed 499K, 12% free 6962K/7879K, paused 12ms+10ms, total 84ms
I/System ( 2948): libcore.io.ErrnoException: kill failed: EPERM (Operation not permitted)
I/System ( 2948): at libcore.io.Posix.kill(Native Method)
I/System ( 2948): at libcore.io.ForwardingOs.kill(ForwardingOs.java:77)
I/System ( 2948): at java.lang.ProcessManager$ProcessImpl.destroy(ProcessManager.java:260)
I/System ( 2948): at com.blablabla.android.core.device.debug.DebugDevice.destroyProcess(DebugDevice.java:127)
I/System ( 2948): at com.blablabla.android.core.device.debug.DebugDevice.cancelLogcatToFile(DebugDevice.java:98)
检查this后,我用建议的解决方案修改了我的cancelLogcatToFile,所以我的代码是这样的:
private void exportLogcatToFile(String fileName) {
String command = new StringBuffer("logcat -f ").append(fileName)
.append("\n").toString();
try {
logcatToFileProcess = Runtime.getRuntime().exec("su");
final DataOutputStream os = new DataOutputStream(
logcatToFileProcess.getOutputStream());
os.writeBytes(command);
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
并终止进程:
private void cancelLogcatToFile() {
if (logcatToFileProcess != null) {
// logcatToFileProcess.destroy();
destroyProcess(logcatToFileProcess);
logcatToFileProcess = null;
}
}
private static void destroyProcess(Process process) {
try {
if (process != null) {
// use exitValue() to determine if process is still running.
process.exitValue();
}
} catch (IllegalThreadStateException e) {
// process is still running, kill it.
process.destroy();
}
}
谢谢!
编辑:此代码将在有根设备中执行,因此su 不会有问题。
另外,我知道我可以做类似killall logcat 的事情,但我想让另一个 logcat 进程保持活动状态
【问题讨论】:
-
su在大多数安卓设备上不可用。这仅适用于有根设备吗? -
它适用于默认root的特定android设备
-
您是否尝试获取进程 PID 并发送
kill命令? -
我不知道如何从使用 Runtime.getRuntime().exec() 创建的进程中检索 PID。
-
不幸的是 java.lang.Process 似乎没有公开底层的本机 PID。您可能可以通过 /proc/pid 像 killall 命令一样寻找候选人来解决这个问题。