package com.basic.security.manager.erlang; import android.os.SystemClock; import android.util.Log; import com.basic.security.base.BaseApplication; import com.basic.security.utils.Constants; import com.jaredrummler.android.shell.CommandResult; import com.jaredrummler.android.shell.Shell; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class ErlangProcess { public static boolean needRestartErlProcess = true; public static boolean erlangProcessStarted = false; public static boolean erlangProcessCanStart = false; public static void restartErlangProcess() { try { /*new Thread(){ @Override public void run() { try { erlangProcessStarted = false; stopErlangProcess(); long start = System.currentTimeMillis(); CommandResult commandResult = Shell.SU.run("cd /data/data/com.basic.security/files/erlang/", "export LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib/", "/data/data/com.termux/files/usr/bin/erl -pa /data/data/com.basic.security/files/erlang/ -name " + Constants.erlangLocalNode + " -setcookie 123 -s socket_server start_server"); System.out.println("end-begin="+(System.currentTimeMillis()-start)); System.out.println(commandResult); erlangProcessStarted = true; } catch (Exception e) { e.printStackTrace(); } } }.start();*/ new MyThread().start(); } catch (Exception e) { e.printStackTrace(); } } public static void start() { BaseApplication.getApplication().executorService.execute(() -> { SqlCacheDeviceManager.downloadSqlCacheList(); DeviceManager.syncDeviceInfoAtAppStart(); SystemClock.sleep(1000); while (true) { if (erlangProcessCanStart) { try { if (erlProcessCount() != 3) { restartErlangProcess(); } else { if (needRestartErlProcess) { restartErlangProcess(); needRestartErlProcess = false; } } } catch (Exception e) { e.printStackTrace(); } } SystemClock.sleep(1000 * 3); } }); } public static List getErlPIDs() { boolean mUseRoot = true; String TAG = "erl"; List syncthingPIDs = new ArrayList(); Process ps = null; DataOutputStream psOut = null; BufferedReader br = null; try { ps = Runtime.getRuntime().exec((mUseRoot) ? "su" : "sh"); psOut = new DataOutputStream(ps.getOutputStream()); psOut.writeBytes("ps\n"); psOut.writeBytes("exit\n"); psOut.flush(); ps.waitFor(); br = new BufferedReader(new InputStreamReader(ps.getInputStream(), "UTF-8")); String line; while ((line = br.readLine()) != null) { if (line.contains("erl")) { String syncthingPID = line.trim().split("\\s+")[1]; syncthingPIDs.add(syncthingPID); } } } catch (IOException | InterruptedException e) { Log.w(TAG, "Failed to list Syncthing processes", e); } finally { try { if (br != null) { br.close(); } if (psOut != null) { psOut.close(); } } catch (IOException e) { Log.w(TAG, "Failed to close psOut stream", e); } if (ps != null) { ps.destroy(); } } return syncthingPIDs; } public static int erlProcessCount() { return getErlPIDs().size(); } public static void stopErlangProcess() { try { List erlPids = getErlPIDs(); for (String erlPid : erlPids) { try { Shell.SU.run("kill -9 " + erlPid); } catch (Exception e) { System.out.println("stopErlangProcess " + e.getMessage()); } } } catch (Exception e) { e.printStackTrace(); } } // 将线程类声明为私有的静态内部类避免了内存泄漏问题 private static class MyThread extends Thread { @Override public void run() { try { erlangProcessStarted = false; stopErlangProcess(); long start = System.currentTimeMillis(); CommandResult commandResult = Shell.SU.run("cd /data/data/com.basic.security/files/erlang/", "export LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib/", "/data/data/com.termux/files/usr/bin/erl -pa /data/data/com.basic.security/files/erlang/ -name " + Constants.erlangLocalNode + " -setcookie 123 -s socket_server start_server"); System.out.println("end-begin=" + (System.currentTimeMillis() - start)); System.out.println(commandResult); erlangProcessStarted = true; } catch (Exception e) { e.printStackTrace(); } } } }