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