Tuesday 5 January 2021

React Native HeadlessJs task call with android WorkManager

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();
    }
}


from React Native HeadlessJs task call with android WorkManager

No comments:

Post a Comment