原标题: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起来,在程序应用里面,结束掉这个进程,不一会了,又自动起来了~~~~跟流氓软件一个样,没错,就是这么贱…
这边是运行在谷歌的原生系统上,Android版本为5.0… 在其他系统下稳定性还远远不足,但是要真正做到杀不死服务几乎是不可能的。 总结一下就是:服务常驻要应对的不是各种难的技术,而是各大ROM。QQ为什么不会被杀死,是因为国内各大ROM不想让他死…
本文主要提供的是一个思路,实现还有诸多不足之处,菜鸟之作,不喜勿喷。
最后附上本例的源代码:Android 通过JNI实现双守护进程
http://download.csdn.net/detail/yyh352091626/9410153
关注「安卓开发精选」
看更多精选安卓技术文章
责任编辑: