Reputation: 328
I'm creating a React Native background sync task with Android WorkManager. The doWork method in WorkManager class is called periodically, correctly. The problem I'm facing is how to call the react native function from the doWork method. In my current implementation the JavaScript function is not called.
Headless Task in React Native
// index.js
AppRegistry.registerHeadlessTask('SyncHeadlessTask', () => SyncHeadlessTask);
// SyncHeadlessTask.js
module.exports = async (taskData) => {
console.log('task running');
};
My HeadlessTask in Java
public class SyncHeadlessTaskService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
return new HeadlessJsTaskConfig(
"SyncHeadlessTask",
Arguments.fromBundle(extras),
10000, // timeout for the task
true // optional: defines whether or not the task is allowed in foreground. Default is false
);
}
return null;
}
}
My Worker
public class SyncWorker extends Worker {
private static final String TAG = "SyncWorker";
public SyncWorker(@Nonnull Context context, @Nonnull WorkerParameters workerParams) {
super(context, workerParams);
}
@Nonnull
@Override
public Result doWork() {
return Result.success();
}
}
My Module
public class SyncModule extends ReactContextBaseJavaModule {
private static final String MODULE_NAME = "SyncManager";
private Context mContext;
private PeriodicWorkRequest workRequest;
private static final String TAG = "SyncModule";
SyncModule(@Nonnull ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
workRequest = new PeriodicWorkRequest.Builder(SyncWorker.class, 15, TimeUnit.MINUTES).build();
}
@ReactMethod
public void startSync() {
WorkManager.getInstance().enqueueUniquePeriodicWork("SyncWork", ExistingPeriodicWorkPolicy.KEEP, workRequest);
}
@ReactMethod
public void stopSync() {
WorkManager.getInstance().cancelUniqueWork("SyncWork");
}
@Nonnull
@Override
public String getName() {
return MODULE_NAME;
}
}
My Package
public class SyncPackage implements ReactPackage {
@Nonnull
@Override
public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new SyncModule(reactContext));
return modules;
}
@Nonnull
@Override
public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Upvotes: 5
Views: 2008
Reputation: 682
You need start your task as a service:
@Nonnull
@Override
public Result doWork() {
Intent service = new Intent(getApplicationContext(), SyncHeadlessTaskService.class);
Bundle bundle = new Bundle();
bundle.putString("foo", "bar");
service.putExtras(bundle);
getApplicationContext().startService(service);
return Result.success();
}
Don't forget to configure your AndroidManifest:
<service android:name="your.package.SyncHeadlessTaskService" />
Upvotes: 3