android使用JNI进程守护service

最近公司一个应用需要让应用启动后不能被360和一些清理内存工具杀死,然后搜索一些相关的资料确定了下面的方法进行进程的守护:使用jni fork出一个子进程用select方法检测管道是否可读,主体进程打开新建管道的写端,当主进程死亡时 写端自动关闭,select检测退出,然后启动service。


注意:这个方法在android5.0以上系统和部分小米机型不行,因为5.0以上的系统killbackgroundprocesses会杀死所有和当前被杀死APK的USERID一样的进程,由于守护进程的所有者和apk的USERID是一样的,所以会被同时杀死,导致进程守护失败。我试过用setuid去修改userid但是没有root权限是不可行的,如果有root权限就能将子进程的userid改成root,从而可以完美的实现守护的功能。


下面附上详细的实现过程:


  1. 需要从java端传入app的数据路径用于创建管道,进行进程监听

  2. 最好创建自身的application applicationoncreate的时候就进行进程监听。


JNI部分java代码:

public class GuardNative {
	static
	{
		System.loadLibrary("Guard");
	}
	public native void Init(String appPath);
	public native void GuardService(String name);
}

JNI部分C代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include 
#include 
int OpenFifo(const char* filePath, int mode);
char* Jstring2String(JNIEnv *env, jstring jstr);
jstring String2Jstring(JNIEnv *env, const char* pat);
extern "C"
{
#include 
#define LOG_TAG "JNI_LOG"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
char g_Path[256];
char g_fifoPath[256];

void Java_com_example_guradprocess_GuardNative_Init(JNIEnv* env, jobject obj,
		jstring jPath)
{

	strcpy(g_Path, Jstring2String(env, jPath));
	strcpy(g_fifoPath, g_Path);
	strcat(g_fifoPath, "/fifo");
	LOGI("g_fifoPath=%s", g_Path);
}
void Java_com_example_guradprocess_GuardNative_GuardService(JNIEnv* env,
		jobject obj, jstring jServiceName)
{
	char* chServiceName = Jstring2String(env, jServiceName);
	pid_t pid = fork();
	if (pid == 0)
	{
		LOGI("this is child process!");
		char buf[128] =
		{ 0 };
		int readfd = OpenFifo(g_fifoPath, O_RDONLY);
		fd_set fdSet;
		FD_ZERO(&fdSet);
		FD_SET(readfd, &fdSet);
		int ret = select(readfd + 1, &fdSet, NULL, NULL, NULL);
		close(readfd);

		LOGI("father process is die!");
		char cmd[256] = "";
		sprintf(cmd, "am startservice --user 0 -n %s", chServiceName);
		LOGI("pid=%d\n%s", getpid(), cmd);
		system(cmd);
		LOGI("GuardService end!");
		exit(0);
	}
	else if (pid > 0)
	{
		LOGI("this is father process!");
		int writefd = OpenFifo(g_fifoPath, O_WRONLY);
	}
	else
	{
		LOGE("fork process error!");
	}
}
}
int OpenFifo(const char* filePath, int mode)
{
	int filefd = -1;
	if (access(filePath, 0) != 0)
	{
		if (mkfifo(filePath, S_IFIFO | 0666) == -1)
		{
			printf("mkfifo error!\n");
		}
	}
	if (-1 == (filefd = open(filePath, mode)))
	{
		printf("open fifo error!\n");
	}
	return filefd;
}
char* Jstring2String(JNIEnv *env, jstring jstr)
{
	char* rtn = NULL;
	jclass clsstring = env->FindClass("java/lang/String");
	jstring strencode = env->NewStringUTF("utf-8");
	jmethodID mid = env->GetMethodID(clsstring, "getBytes",
			"(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
	jsize alen = env->GetArrayLength(barr);
	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if (alen > 0)
	{
		rtn = (char*) malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	env->ReleaseByteArrayElements(barr, ba, 0);
	return rtn;
}

//char* to jstring
jstring String2Jstring(JNIEnv *env, const char* pat)
{
	jclass strClass = env->FindClass("Ljava/lang/String;");
	jmethodID ctorID = env->GetMethodID(strClass, "",
			"([BLjava/lang/String;)V");
	jbyteArray bytes = env->NewByteArray(strlen(pat));
	env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);
	jstring encoding = env->NewStringUTF("utf-8");
	return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
}


JNI mk文件

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := Guard
LOCAL_SRC_FILES := \
	GuradNative.cpp 
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

java调用守护的方法代码:

public class TestApplication extends Application {
	GuardNative Guard = new GuardNative();
	@Override
	public void onCreate() {
		super.onCreate();
		Guard.Init(getCacheDir().toString());
		Guard.GuardService("com.example.guradprocess/com.example.guradprocess.TestService");
	}
}


项目代码下载:http://download.csdn.net/detail/csdn49532/9377011。




你可能感兴趣的:(安卓JNI)