android jni守护进程,Android 通过JNI实现守护进程(下)

(点击上方公众号,可快速关注)

来源:LeBron_Six

链接:blog.csdn.net/yyh352091626/article/details/50542554

接上文

C/C++端关键的部分主要是以上这些,接下来就是Java端调用。

首先来看一下so库的加载类,以及C++函数的调用:

packagecom.yyh.fork;

importjava.io.DataInputStream;

importjava.io.DataOutputStream;

importjava.io.File;

publicclassNativeRuntime{

privatestaticNativeRuntimetheInstance=null;

privateNativeRuntime(){

}

publicstaticNativeRuntime getInstance(){

if(theInstance==null)

theInstance=newNativeRuntime();

returntheInstance;

}

/**

* RunExecutable 启动一个可自行的lib*.so文件

* @date 2016-1-18 下午8:22:28

* @param pacaageName

* @param filename

* @param alias 别名

* @param args 参数

* @return

*/

publicStringRunExecutable(StringpacaageName,Stringfilename,Stringalias,Stringargs){

Stringpath="/data/data/"+pacaageName;

Stringcmd1=path+"/lib/"+filename;

Stringcmd2=path+"/"+alias;

Stringcmd2_a1=path+"/"+alias+" "+args;

Stringcmd3="chmod 777 "+cmd2;

Stringcmd4="dd if="+cmd1+" of="+cmd2;

StringBuffersb_result=newStringBuffer();

if(!newFile("/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(";");

returnsb_result.toString();

}

/**

* 执行本地用户命令

* @date 2016-1-18 下午8:23:01

* @param pacaageName

* @param command

* @param sb_out_Result

* @return

*/

publicbooleanRunLocalUserCommand(StringpacaageName,Stringcommand,StringBuffersb_out_Result){

Processprocess=null;

try{

process=Runtime.getRuntime().exec("sh");// 获得shell进程

DataInputStreaminputStream=newDataInputStream(process.getInputStream());

DataOutputStreamoutputStream=newDataOutputStream(process.getOutputStream());

outputStream.writeBytes("cd /data/data/"+pacaageName+"\n");// 保证在command在自己的数据目录里执行,才有权限写文件到当前目录

outputStream.writeBytes(command+" &\n");// 让程序在后台运行,前台马上返回

outputStream.writeBytes("exit\n");

outputStream.flush();

process.waitFor();

byte[]buffer=newbyte[inputStream.available()];

inputStream.read(buffer);

Strings=newString(buffer);

if(sb_out_Result!=null)

sb_out_Result.append("CMD Result:\n"+s);

}catch(Exceptione){

if(sb_out_Result!=null)

sb_out_Result.append("Exception:"+e.getMessage());

returnfalse;

}

returntrue;

}

publicnativevoidstartActivity(Stringcompname);

publicnativeStringstringFromJNI();

publicnativevoidstartService(Stringsrvname,Stringsdpath);

publicnativeintfindProcess(Stringpackname);

publicnativeintstopService();

static{

try{

System.loadLibrary("helper");// 加载so库

}catch(Exceptione){

e.printStackTrace();

}

}

}

然后,我们在收到开机广播后,启动该服务。

packagecom.yyh.activity;

importandroid.content.BroadcastReceiver;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.util.Log;

importcom.yyh.fork.NativeRuntime;

importcom.yyh.utils.FileUtils;

publicclassPhoneStatReceiverextendsBroadcastReceiver{

privateStringTAG="tag";

@Override

publicvoidonReceive(Contextcontext,Intentintent){

if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){

Log.i(TAG,"手机开机了~~");

NativeRuntime.getInstance().startService(context.getPackageName()+"/com.yyh.service.HostMonitor",FileUtils.createRootPath());

}elseif(Intent.ACTION_USER_PRESENT.equals(intent.getAction())){

}

}

}

Service服务里面,就可以做该做的事情。

packagecom.yyh.service;

importandroid.app.Service;

importandroid.content.Intent;

importandroid.os.IBinder;

importandroid.util.Log;

publicclassHostMonitorextendsService{

@Override

publicvoidonCreate(){

super.onCreate();

Log.i("daemon_java","HostMonitor: onCreate! I can not be Killed!");

}

@Override

publicintonStartCommand(Intentintent,intflags,intstartId){

Log.i("daemon_java","HostMonitor: onStartCommand! I can not be Killed!");

returnsuper.onStartCommand(intent,flags,startId);

}

@Override

publicIBinder onBind(Intentarg0){

returnnull;

}

}

当然,也不要忘记在Manifest.xml文件配置receiver和service:

android:name="com.yyh.activity.PhoneStatReceiver"

android:enabled="true"

android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

android:enabled="true"

android:exported="true">

run起来,在程序应用里面,结束掉这个进程,不一会了,又自动起来了~~~~跟流氓软件一个样,没错,就是这么贱…

0818b9ca8b590ca3270a3433284dd417.png

这边是运行在谷歌的原生系统上,Android版本为5.0… 在其他系统下稳定性还远远不足,但是要真正做到杀不死服务几乎是不可能的。 总结一下就是:服务常驻要应对的不是各种难的技术,而是各大ROM。QQ为什么不会被杀死,是因为国内各大ROM不想让他死…

本文主要提供的是一个思路,实现还有诸多不足之处,菜鸟之作,不喜勿喷。

最后附上本例的源代码:Android 通过JNI实现双守护进程

http://download.csdn.net/detail/yyh352091626/9410153

关注「安卓开发精选」看更多精选安卓技术文章↓↓↓

0818b9ca8b590ca3270a3433284dd417.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值