Android中实现开机自动启动服务(service)实例
最近在将HevSocks5Client移植到Android上了,在经过增加signalfd和timerfd相关的系统调用支持后,就可以直接使用NDK编译出executable了。直接的nativeexectuable在Android系统总还是不太方便用哦。还是做成一个apk吧,暂定只写一个service并开机自动启用,无activity的。
Java中调用native程序我选择使用JNI方式,直接在JNI_OnLoad方法中调用pthread_create创建个线程跑原来的main就行啦。
...
#ifdefined(ANDROID)
#include<jni.h>
#include<pthread.h>
#endif
int
main(intargc,char*argv[])
{
...
}
#ifdefined(ANDROID)
staticvoid*
thread_handler(void*data)
{
main(0,NULL);
returnNULL;
}
jint
JNI_OnLoad(JavaVM*vm,void*reserved)
{
pthread_tthread;
pthread_create(&thread,NULL,thread_handler,NULL);
returnJNI_VERSION_1_4;
}
#endif
Android服务
服务主要是加载JNI接口的hev-socks5-client库,使服务跑起来。
packagehev.socks5;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.util.Log;
publicclassMainServiceextendsService{
static{
System.loadLibrary("hev-socks5-client");
}
publicIBinderonBind(Intentintent){
returnnull;
}
}
BroadcastReceiver
ServiceReceiver的功能就是监听系统上的BOOT_COMPLETED事件,用于实现自动启动服务。
packagehev.socks5;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
publicclassServiceReceiverextendsBroadcastReceiver{
@Override
publicvoidonReceive(Contextcontext,Intentintent){
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Intenti=newIntent(context,MainService.class);
context.startService(i);
}
}
}
AndroidManifest.xml
最后,要在Manifest中注册Service和Receiver,增加上访问Internet和Bootcompleted的权限。
<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="hev.socks5"
android:versionCode="1"
android:versionName="1.0">
<applicationandroid:label="@string/app_name">
<serviceandroid:name=".MainService">
<intent-filter>
<actionandroid:name="hev.socks5.MainService"/>
</intent-filter>
</service>
<receiverandroid:enabled="true"android:name=".ServiceReceiver">
<intent-filter>
<actionandroid:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
<uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
</manifest>
Tips
此方法仅在Android2.3.3及之前版本有效,之后版本如果此应用在安装后从没运行过,BroadcastReceiver将接收不到bootcompleted的action,解决方法是使用命令手动启动一下service。
amstartservicehev.socks5/.MainService