linux java app 保活,Android组件保活,service保活

首先介绍一下android的进程. Android 进程分为两种 :其一,java层的进程,也就是在虚拟机里运行的进程,他们的父进程是zygote进程,我们平时调用的AM里面的类似getrunningprocess()方法,返回的就是这类进程信息,这类进程很容易被杀死。其二,native层的原生进程 也就是linux c的进程,这类进程比较安全,其中父进程是init进程的更加安全,很难杀死,在linux里叫守护进程,像surfaceflinger(控制界面呈现)进程,一旦启动会在底层一直运行。

那么 我们的目的就是要写一个守护进程 实时监视自己app java层进程的情况 如果被杀死 就立即创建。

首先是最重要的守护程序代码 linuxC的 带注释

#include #include #include #include #include #include #include #include /**

*守护进程的名字"/proc/pid/status"文件的第一行 linux内核把所有进程信息的节点映射在了"/proc"下

*注意不同android版本 status里进程名字格式可能不一样

*楼主的4.0.3是下面这行 具体的自己到/proc里看一下

**/

char *procdeam = "Name: com.gy.textndk";

//判断进程是否还在运行

int ifprocrun(char *rootpath)

{

DIR *dir;

struct dirent *ptr; //遍历文件夹需要dirent结构体

int bufsize = strlen(procdeam);

if((dir = opendir(rootpath)) == NULL)

{

perror("dir opened failed\n");

exit(1);

}

//遍历"/proc"下所有文件夹

while((ptr = readdir(dir)) != NULL)

{

if(ptr->d_type == 4)

{

char path[128];

memset(path,'\0',sizeof(path));

strcpy(path,rootpath);

strcat(path,"/");

strcat(path,ptr->d_name);

strcat(path,"/status");

//判断是否存在"status" 文件

if(access(path,F_OK) != -1)

{

int fd = open(path,O_RDONLY);

char tmp_buf[bufsize];

read(fd,tmp_buf,bufsize);

close(fd);

printf(tmp_buf,"\n");

//判断进程名是否相等

if(strcmp(tmp_buf,procdeam) == 0)

{

printf("-----------------proc is running------------------\n");

return 1;

}

}

}

}

return 0;

}

int main()

{

int i;

int fd;

//1.创建子进程,结束父进程,子进程由init接管成为守护进程

pid_t pid = fork();

if(pid<0)

exit(1);

else if(pid>0)

exit(0);

//设置新的 session

setsid();

//2.关闭所有fd管道

for(i=0;i<=48608;i++)

{

close(i);

}

//3.改变工作目录到跟文件夹

chdir("/");

//4.umask

umask(0);

//5.do sth

while(1)

{

if(ifprocrun("/proc") == 0)

{

//调用app_process 的命令 "com.gy.Autostart_Activity"这个实在manifest里注册的 intent-filter action

//自己定义 这样AMS才能根据action启动你app组件 类似注册表

system("am start -a com.gy.Autostart_Activity");

}

sleep(10); //10s判断一次 自己定

}

}

上面这个程序不能用arm-linux-gcc编译 因为不支持 android新版的 程序调用接口,用 ndk-build命令编译 源码放在名叫的jni目录下

接下来就是实现把编译好的linux c守护程序打包进apk并在安装时将其释放到data目录下,便于运行。

首先将编译好的linux c程序放进assets文件夹下面就是java层释放assets资源文件并且运行的代码,涉及jni

package com.gy.textndk;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import android.app.Activity;

import android.content.Context;

import android.util.Log;

import android.widget.TextView;

import android.os.Bundle;

public class HelloJni extends Activity

{

/** Called when the activity is first created. */

private static String TAG = "gy";

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

/* Create a TextView and set its content.

* the text is retrieved by calling a native

* function.

*/

TextView tv = new TextView(this);

tv.setText( stringFromJNI() );

setContentView(tv);

StringBuilder sb = new StringBuilder();

sb.append(getAppPrivateDir(this)).append("/gyarmdeomproc");

copyAsset(HelloJni.this, "gyarmdeomproc", sb.toString());

startproc();

}

/* A native method that is implemented by the

* 'hello-jni' native library, which is packaged

* with this application.

*/

public native String stringFromJNI();

/* This is another native method declaration that is *not*

* implemented by 'hello-jni'. This is simply to show that

* you can declare as many native methods in your Java code

* as you want, their implementation is searched in the

* currently loaded native libraries only the first time

* you call them.

*

* Trying to call this function will result in a

* java.lang.UnsatisfiedLinkError exception !

*/

public native String unimplementedStringFromJNI();

public native int startproc();

/* this is used to load the 'hello-jni' library on application

* startup. The library has already been unpacked into

* /data/data/com.example.hellojni/lib/libhello-jni.so at

* installation time by the package manager.

*/

static {

System.loadLibrary("hello-jni");

}

//文件复制

public static boolean copyStream(InputStream in, OutputStream out) {

Log.d(TAG, "copyStream("+ in + " ," + out+ ")");

try {

byte[] buf = new byte[8192];

int len;

while ((len = in.read(buf)) > 0)

out.write(buf, 0, len);

} catch (Exception e) {

e.printStackTrace();

return false;

}

return true;

}

//获得app私有文件夹路径

public static String getAppPrivateDir(Context ctx) {

File dataDir = ctx.getDir("data", Context.MODE_PRIVATE);

return dataDir.getAbsolutePath();

}

//拷贝assets资源文件到data私有文件夹下

public static boolean copyAsset(Context ctx, String assetFile,

String saveToFile) {

Log.d(TAG, "copyAssets(" + assetFile + " -> " + saveToFile);

File outputFile = new File(saveToFile);

if (outputFile.exists()) {

return true;

}

// init output stream(file)

OutputStream out;

try {

out = new FileOutputStream(outputFile);

} catch (FileNotFoundException e1) {

e1.printStackTrace();

return false;

}

boolean copyResult = false;

InputStream in = null;

try {

in = ctx.getAssets().open(assetFile);

copyResult = copyStream(in, out);

Log.d(TAG, "copy " + assetFile + " - " + copyResult);

} catch (IOException e1) {

e1.printStackTrace();

} finally {

// close input stream(file)

try {

if (in != null)

in.close();

} catch (IOException e) {

}

}

// close output stream (file)

try {

if (out != null)

out.close();

} catch (IOException e) {

e.printStackTrace();

}

// return copy result

// add file execute permission

File fs = new File(saveToFile);

try {

//这句很重要 赋予文件可执行权限 不然文件无法执行

fs.setExecutable(true, true);

} catch (Exception e) {

e.printStackTrace();

}

Log.d(TAG, "copyAsset() return " + copyResult);

return copyResult;

}

}

最后 是jni的c代码 很简单 直接调用

/*

* deomproc.c

*

* Created on: 2015年2月9日

* Author: gy

#include #include #include JNIEXPORT jint JNICALL Java_com_gy_textndk_HelloJni_startproc()

{

system("/data/data/com.gy.textndk/app_data/gyarmdeomproc");

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值