首先介绍一下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);//设置新的 sessionsetsid();//2.关闭所有fd管道 for(i=0;i<=48608;i++){close(i);}//3.改变工作目录到跟文件夹chdir("/");//4.umaskumask(0);//5.do sthwhile(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";@Overridepublic 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 permissionFile 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");}


更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  6. [置顶] android 基础笔试题
  7. Android搭建Ftp服务器监听文件传输状态
  8. 全自动化的 Android(安卓)编译管线
  9. Android(安卓)JNI和NDK学习(02)--静态方式实现JNI

随机推荐

  1. 来点基础的--诡异的极客们的符号--流、管
  2. Linux Box上运行哪个SQL服务器?
  3. linux中创建公私钥
  4. 报告节选3:Linux比例近半 操作系统混战虚
  5. 继续问linux下c问题
  6. 嵌入式Linux系统工程师系列之ARM920T的MM
  7. find . -type f ! -name "*.o" 排除某类
  8. 解决找不到动态库libpthread.so
  9. PHP通过SSH操作远程服务器(linux)
  10. Linux和Windows下重启MySQL方法--方便查