Recently, I have ported HevSocks5Client to Android. After adding signalfd and timerfd-related system call support, you can directly compile executable using NDK. Direct native execute is still not very convenient to use on Android systems. It’s better to make an apk, and it is tentatively written only one service and automatically enabled when it is turned on, without activity.
To call native programs in Java, I chose to use JNI method, and directly call pthread_create in the JNI_OnLoad method to create a thread to run the original main.
...
#if defined(ANDROID)
#include <>
#include <>
#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 Services
The service mainly loads the hev-socks5-client library of the JNI interface to make the service run.
package hev.socks5;
import ;
import ;
import ;
import ;
public class MainService extends Service {
static {
("hev-socks5-client");
}
public IBinder onBind(Intent intent) {
return null;
}
}
BroadcastReceiver
The function of ServiceReceiver is to listen to the BOOT_COMPLETED event on the system, which is used to automatically start the service.
package hev.socks5;
import ;
import ;
import ;
public class ServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent(context, );
(i);
}
}
}
Finally, register Service and Receiver in Manifest and increase access to the Internet and Boot completed.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:andro
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." />
</intent-filter>
</service>
<receiver android:enabled="true" android:name=".ServiceReceiver">
<intent-filter>
<action android:name=".BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="" />
<uses-permission android:name=".RECEIVE_BOOT_COMPLETED" />
</manifest>
Tips
This method is only valid in Android 2.3.3 and previous versions. If this application has never been run after installation, Broadcast Receiver will not receive the boot completed action. The solution is to use the command to manually start the service.