首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Headless JS

需要本机代码的项目

此页面仅适用于react-native init使用Create React Native App 制作的或使用此类应用程序弹出的项目。有关弹出的更多信息,请参阅创建React Native App存储库的指南

Headless JS是一种在您的应用程序处于后台时使用JavaScript运行任务的方式。例如,它可用于同步新数据,处理推送通知或播放音乐。

The JS API

任务是您注册的简单异步功能AppRegistry,与注册React应用程序类似:

代码语言:javascript
复制
AppRegistry.registerHeadlessTask('SomeTaskName', () => require('SomeTaskName'));

然后,在SomeTaskName.js

代码语言:javascript
复制
module.exports = async (taskData) => {
  // do stuff
}

只要不触及用户界面,您就可以在任务中执行任何操作:网络请求,定时器等等。一旦您的任务完成(即承诺已解决),React Native将进入“已暂停”模式(除非有其他任务正在运行,或者有前台应用程序)。

The Java API

是的,这仍然需要一些本机代码,但它非常薄。您需要扩展HeadlessJsTaskService并覆盖getTaskConfig,例如:

代码语言:javascript
复制
public class MyTaskService extends HeadlessJsTaskService {

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

然后将该服务添加到您的AndroidManifest.xml文件中:

代码语言:javascript
复制
<service android:name="com.example.MyTaskService" />

现在,无论何时你开始你的服务(https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent%29)),例如作为一项周期性任务或响应某个系统事件/广播,JS会旋转起来,运行你的任务,然后停下来。

例:

代码语言:javascript
复制
Intent service = new Intent(getApplicationContext(), MyTaskService.class);
Bundle bundle = new Bundle();

bundle.putString("foo", "bar");
service.putExtras(bundle);

getApplicationContext().startService(service);

注意事项

  • 默认情况下,如果您尝试在应用处于前台时运行任务,您的应用将崩溃。这是为了防止开发人员通过在任务中执行大量工作并放慢用户界面的速度而在脚下自我拍摄。您可以传递第四个boolean参数来控制此行为。
  • 如果您从开始您的服务BroadcastReceiver,请确保HeadlessJsTaskService.acquireWakeLockNow()在从返回之前致电onReceive()

使用示例

服务可以从Java API启动。首先,您需要决定何时启动服务并相应地实施您的解决方案。这是一个简单的例子,对网络连接变化做出反应。

以下几行显示了用于注册广播接收器的Android清单文件的一部分。

代码语言:javascript
复制
<receiver android:name=".NetworkChangeReceiver" >
  <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  </intent-filter>
</receiver>

广播接收机然后处理在onReceive函数中广播的意图。这是检查您的应用程序是否在前台的好地方。如果应用程序不在前台,我们可以准备启动的意图,没有使用putExta捆绑的信息或附加信息(请记住,捆绑包只能处理可调参数值)。最终,服务开始并获得wakelock。

代码语言:javascript
复制
public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        /**
          This part will be called everytime network connection is changed
          e.g. Connected -> Not Connected
        **/
        if (!isAppOnForeground((context))) {
            /**
              We will start our service and send extra info about 
              network connections
            **/
            boolean hasInternet = isNetworkAvailable(context);
            Intent serviceIntent = new Intent(context, MyTaskService.class);
            serviceIntent.putExtra("hasInternet", hasInternet);
            context.startService(serviceIntent);
            HeadlessJsTaskService.acquireWakeLockNow(context);
        }
    }

    private boolean isAppOnForeground(Context context) {
        /**
          We need to check if app is in foreground otherwise the app will crash.
         http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
        **/
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = 
        activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
            return false;
        }
        final String packageName = context.getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == 
            ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
             appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) 
        context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return (netInfo != null && netInfo.isConnected());
    }


}

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com