使用 android WorkManager 响应 Native HeadlessJs 任务调用

cam*_*lle 5 android react-native android-workmanager

我正在使用 Android WorkManager 创建一个 React Native 后台同步任务。WorkManager 类中的 doWork 方法被定期、正确地调用。我面临的问题是如何从 doWork 方法调用 React Native 函数。在我当前的实现中,未调用 JavaScript 函数。

React Native 中的无头任务

// index.js
AppRegistry.registerHeadlessTask('SyncHeadlessTask', () => SyncHeadlessTask);

// SyncHeadlessTask.js
module.exports = async (taskData) => {
    console.log('task running');
};
Run Code Online (Sandbox Code Playgroud)

我的 Java 中的 HeadlessTask

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的工人

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的模块

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的包裹

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 3

您需要将任务作为服务启动:

@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();
}
Run Code Online (Sandbox Code Playgroud)

不要忘记配置您的 AndroidManifest:

<service android:name="your.package.SyncHeadlessTaskService" />
Run Code Online (Sandbox Code Playgroud)