In Android the startup service of service instance is realized automatically

  • 2020-06-01 11:01:29
  • OfStack

Recently, HevSocks5Client was ported to Android. After adding signalfd and timerfd related system call support, executable can be compiled directly using NDK. Direct native exectuable is still not easy to use on the Android system. Make it 1 apk, temporarily only 1 service and start it automatically, no activity.

Java calls native. I choose JNI and call pthread_create directly from JNI_OnLoad to create a thread to run main.


...
#if defined(ANDROID)
#include <jni.h>
#include <pthread.h>
#endif

int
main (int argc, char *argv[])
{
    ...
}

#if defined(ANDROID)
static void *
thread_handler (void *data)
{
    main (0, NULL);
    return NULL;
}

jint
JNI_OnLoad (JavaVM *vm, void *reserved)
{
    pthread_t thread;
    pthread_create (&thread, NULL, thread_handler, NULL);
    return JNI_VERSION_1_4;
}
#endif


Android service

The service basically loads the hev-socks5-client library of the JNI interface to make the service run.


package hev.socks5;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MainService extends Service {

        static {
                System.loadLibrary("hev-socks5-client");
        }

        public IBinder onBind(Intent intent) {
                return null;
        }
}

BroadcastReceiver

The function of ServiceReceiver is to listen for the BOOT_COMPLETED event on the system, which is used to automatically start the service.


package hev.socks5;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class ServiceReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
                        Intent i = new Intent(context, MainService.class);
                        context.startService(i);
                }
        }
}


AndroidManifest.xml

Finally, register Service and Receiver in Manifest, adding access to Internet and Boot completed.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="hev.socks5"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:label="@string/app_name" >
                <service android:name=".MainService">
                        <intent-filter>
                                <action android:name="hev.socks5.MainService" />
                        </intent-filter>
                </service>
                <receiver android:enabled="true" android:name=".ServiceReceiver">
                        <intent-filter>
                                <action android:name="android.intent.action.BOOT_COMPLETED" />
                        </intent-filter>
                </receiver>
        </application>
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>

Tips

This method is only valid for Android 2.3.3 and before. If the application never runs after installation, Broadcast Receiver will not receive action of boot completed. The solution is to manually start service 1 using the command.

am startservice hev.socks5/.MainService


Related articles: