/**
* srvname 进程名
* sd 之前创建子进程的pid写入的文件路径
*/
int start(int argc, char* srvname, char* sd) {
pthread_t id;
int ret;
struct rlimit r;
int pid = fork();
LOGI("fork pid: %d", pid);
if (pid < 0) {
LOGI("first fork() error pid %d,so exit", pid);
exit(0);
} else if (pid != 0) {
LOGI("first fork(): I'am father pid=%d", getpid());
//exit(0);
} else { // 第一个子进程
LOGI("first fork(): I'am child pid=%d", getpid());
setsid();
LOGI("first fork(): setsid=%d", setsid());
umask(0); //为文件赋予更多的权限,因为继承来的文件可能某些权限被屏蔽
int pid = fork();
if (pid == 0) { // 第二个子进程
// 这里实际上为了防止重复开启线程,应该要有相应处理
LOGI("I'am child-child pid=%d", getpid());
chdir("/"); //<span style="font-family: Arial, Helvetica, sans-serif;">修改进程工作目录为根目录,chdir(“/”)</span>
//关闭不需要的从父进程继承过来的文件描述符。
if (r.rlim_max == RLIM_INFINITY) {
r.rlim_max = 1024;
}
int i;
for (i = 0; i < r.rlim_max; i++) {
close(i);
}
umask(0);
ret = pthread_create(&id, NULL, (void *) thread, srvname); // 开启线程,轮询去监听启动服务
if (ret != 0) {
printf("Create pthread error!\n");
exit(1);
}
int stdfd = open ("/dev/null", O_RDWR);
dup2(stdfd, STDOUT_FILENO);
dup2(stdfd, STDERR_FILENO);
} else {
exit(0);
}
}
return 0;
}
/**
* 启动Service
*/
void Java_com_yyh_fork_NativeRuntime_startService(JNIEnv* env, jobject thiz,
jstring cchrptr_ProcessName, jstring sdpath) {
char * rtn = jstringTostring(env, cchrptr_ProcessName); // 得到进程名称
char * sd = jstringTostring(env, sdpath);
LOGI("Java_com_yyh_fork_NativeRuntime_startService run....ProcessName:%s", rtn);
a = rtn;
start(1, rtn, sd);
}
void thread(char* srvname) {
while(1){
check_and_restart_service(srvname); // 应该要去判断service状态,这里一直restart 是不足之处
sleep(4);
}
}
/**
* 检测服务,如果不存在服务则启动.
* 通过am命令启动一个laucher服务,由laucher服务负责进行主服务的检测,laucher服务在检测后自动退出
*/
void check_and_restart_service(char* service) {
LOGI("当前所在的进程pid=",getpid());
char cmdline[200];
sprintf(cmdline, "am startservice --user 0 -n %s", service);
char tmp[200];
sprintf(tmp, "cmd=%s", cmdline);
ExecuteCommandWithPopen(cmdline, tmp, 200);
LOGI( tmp, LOG);
}
/**
* 执行命令
*/
void ExecuteCommandWithPopen(char* command, char* out_result,
int resultBufferSize) {
FILE * fp;
out_result[resultBufferSize - 1] = '\0';
fp = popen(command, "r");
if (fp) {
fgets(out_result, resultBufferSize - 1, fp);
out_result[resultBufferSize - 1] = '\0';
pclose(fp);
} else {
LOGI("popen null,so exit");
exit(0);
}
}
package com.yyh.fork;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
public class NativeRuntime {
private static NativeRuntime theInstance = null;
private NativeRuntime() {
}
public static NativeRuntime getInstance() {
if (theInstance == null)
theInstance = new NativeRuntime();
return theInstance;
}
/**
* RunExecutable 启动一个可自行的lib*.so文件
* @date 2016-1-18 下午8:22:28
* @param pacaageName
* @param filename
* @param alias 别名
* @param args 参数
* @return
*/
public String RunExecutable(String pacaageName, String filename, String alias, String args) {
String path = "/data/data/" + pacaageName;
String cmd1 = path + "/lib/" + filename;
String cmd2 = path + "/" + alias;
String cmd2_a1 = path + "/" + alias + " " + args;
String cmd3 = "chmod 777 " + cmd2;
String cmd4 = "dd if=" + cmd1 + " of=" + cmd2;
StringBuffer sb_result = new StringBuffer();
if (!new File("/data/data/" + alias).exists()) {
RunLocalUserCommand(pacaageName, cmd4, sb_result); // 拷贝lib/libtest.so到上一层目录,同时命名为test.
sb_result.append(";");
}
RunLocalUserCommand(pacaageName, cmd3, sb_result); // 改变test的属性,让其变为可执行
sb_result.append(";");
RunLocalUserCommand(pacaageName, cmd2_a1, sb_result); // 执行test程序.
sb_result.append(";");
return sb_result.toString();
}
/**
* 执行本地用户命令
* @date 2016-1-18 下午8:23:01
* @param pacaageName
* @param command
* @param sb_out_Result
* @return
*/
public boolean RunLocalUserCommand(String pacaageName, String command, StringBuffer sb_out_Result) {
Process process = null;
try {
process = Runtime.getRuntime().exec("sh"); // 获得shell进程
DataInputStream inputStream = new DataInputStream(process.getInputStream());
DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());
outputStream.writeBytes("cd /data/data/" + pacaageName + "\n"); // 保证在command在自己的数据目录里执行,才有权限写文件到当前目录
outputStream.writeBytes(command + " &\n"); // 让程序在后台运行,前台马上返回
outputStream.writeBytes("exit\n");
outputStream.flush();
process.waitFor();
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
String s = new String(buffer);
if (sb_out_Result != null)
sb_out_Result.append("CMD Result:\n" + s);
} catch (Exception e) {
if (sb_out_Result != null)
sb_out_Result.append("Exception:" + e.getMessage());
return false;
}
return true;
}
public native void startActivity(String compname);
public native String stringFromJNI();
public native void startService(String srvname, String sdpath);
public native int findProcess(String packname);
public native int stopService();
static {
try {
System.loadLibrary("helper"); // 加载so库
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.yyh.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.yyh.fork.NativeRuntime;
import com.yyh.utils.FileUtils;
public class PhoneStatReceiver extends BroadcastReceiver {
private String TAG = "tag";
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.i(TAG, "手机开机了~~");
NativeRuntime.getInstance().startService(context.getPackageName() + "/com.yyh.service.HostMonitor", FileUtils.createRootPath());
} else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
}
}
}
package com.yyh.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class HostMonitor extends Service {
@Override
public void onCreate() {
super.onCreate();
Log.i("daemon_java", "HostMonitor: onCreate! I can not be Killed!");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("daemon_java", "HostMonitor: onStartCommand! I can not be Killed!");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
<receiver
android:name="com.yyh.activity.PhoneStatReceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<service android:name="com.yyh.service.HostMonitor"
android:enabled="true"
android:exported="true">
</service>
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有