The react native documentation about this seems more than incomplete. I was following this guide which doesn't seem to lead me anywhere:
https://facebook.github.io/react-native/releases/next/docs/headless-js-android.html#headless-js
Where am I supposed to put the .java file? How am I supposed to start the task?
Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.
React Native background service library for running background tasks forever in Android & iOS. Schedule a background job that will run your JavaScript when your app is in the background or foreground.
React is a JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies. Strapi is an open-source headless CMS built with React. js.
React Native is single-threaded in nature. In its rendering process, rather than have multiple processes occur at the same time (multithreading), other components have to wait when one component is being rendered.
I had the same problem as you did. I'm new to native Android dev and I followed the docs, but they didn't work for me. Turns out I misunderstood and thought that I can start the actual task FROM my react native code. It doesn't work that way, though. You write the JavaScript code you want to run when the task is started, but you need to start that task from native code. So, steps you did already are setting up the task, but nothing is telling them to start.
I'll use my project as an example:
In my JavaScript:
/*
This code basically registers WHAT javascript code
I want to call when the 'disconnect' service is started
*/
const disconnectTask = () => async () => {
if (connectionIsActive) {
user.goOffline();
}
};
AppRegistry.registerHeadlessTask('disconnect', disconnectTask);
Then I created the java file here:
projectroot/android/app/src/main/java/com/mycompany/app/ForceOfflineService.java
package com.mycompany.app;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import com.facebook.react.bridge.WritableMap;
import javax.annotation.Nullable;
public class ForceOfflineService extends HeadlessJsTaskService {
@Override
@Nullable
protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
// WritableMap data = extras != null ? Arguments.fromBundle(extras) : null;
// ---- EDIT ---- the line above no longer works, since null is not an accepted value anymore.
WritableMap data = extras != null ? Arguments.fromBundle(extras) : Arguments.createMap();
// Make sure that the string below ("disconnect" in this case)
// matches the string used to register the task in your JS
return new HeadlessJsTaskConfig(
"disconnect",
data,
5000);
}
}
then inside your android manifest (mine is here: projectroot/android/app/src/main/AndroidManifest.xml) you must register the service inside the application tag
<manifest>
<application>
<!-- other existing configuration -->
<service android:name=".ForceOfflineService" />
</application>
</manifest>
Lastly, you need to use the native code to start the service. In my MainActivity.kt I start the service when the onStop lifecycle hook is called:
override fun onStop() {
super.onStop()
Handler(Looper.getMainLooper()).postDelayed(Runnable {
val service = Intent(applicationContext, ForceOfflineService::class.java)
applicationContext.startService(service)
}, IDLE_TIME_BEFORE_DISCONNECT)
}
and that's it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With