React Native - Headless JS示例

时间:2017-01-20 15:24:09

标签: react-native

关于此的反应原生文档似乎不完整。我正在遵循这个指南,这似乎并没有引导我到任何地方:

https://facebook.github.io/react-native/releases/next/docs/headless-js-android.html#headless-js

我应该把.java文件放在哪里? 我该如何开始这项任务?

2 个答案:

答案 0 :(得分:0)

将.java文件放入项目中。例如。 /app/src/main/java/com/alex/app/service/

如果您想要在不显示ReactRootView的情况下执行特定JavaScript代码,则可以使用自定义HeadlessJsTaskService

要启动任务,只需从其他服务或甚至从活动中调用startService(new Intent(this, MyTaskService.class));

提示: 我更改了教程的getTaskConfig()方法,因此它允许空的额外内容:

@Override
@Nullable
protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
    Bundle extras = intent.getExtras();
    WritableMap data = extras != null ? Arguments.fromBundle(extras) : null;
    return new HeadlessJsTaskConfig(
            "SomeTaskName",
            data,
            5000);
}

或至少改变它,所以如果没有提供额外的话,它不会无声地失败。

答案 1 :(得分:0)

我遇到了和你一样的问题。我是原生 Android 开发人员的新手,我遵循了文档,但它们对我不起作用。结果我误解了,并认为我可以从我的本机代码开始实际任务。但是,它不是那样工作的。您编写要在任务启动时运行的 JavaScript 代码,但您需要从本机代码启动该任务。因此,您已经执行的步骤是设置任务,但没有任何内容告诉他们开始。

我将以我的项目为例:

在我的 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);

然后我在这里创建了 java 文件:

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

然后在你的安卓清单里面 (我的在这里:projectroot/android/app/src/main/AndroidManifest.xml) 您必须在应用程序标签内注册服务

<manifest>
  <application>

    <!-- other existing configuration -->

    <service android:name=".ForceOfflineService" />
  </application>
</manifest>

最后,您需要使用本机代码来启动服务。在我的 MainActivity.kt 中,当调用 onStop 生命周期钩子时启动服务:

 override fun onStop() {
    super.onStop()

    Handler(Looper.getMainLooper()).postDelayed(Runnable {
      val service = Intent(applicationContext, ForceOfflineService::class.java)
      applicationContext.startService(service)
    }, IDLE_TIME_BEFORE_DISCONNECT)
  }

就是这样!