zoukankan      html  css  js  c++  java
  • RN服务

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

      当app在 后台运行 时,我们可以使用RN服务来同时地刷新数据、推送或者播放音乐。

    JS API

      在JS中注册一个后台任务(不能操作UI,一般是网络请求、定时器等)

    AppRegistry.registerHeadlessTask('SomeTaskName', () => require('SomeTaskName'));
    
    // SomeTaskName.js:
    module.exports = async (taskData) => {
      // do stuff
    };

    Java API

      定义一个服务类,继承HeadlessJsTaskService

    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, // timeout for the task
              false // optional: defines whether or not  the task is allowed in foreground. Default is false
            );
        }
        return null;
      }
    }

      在清单文件中声明这个服务

    <service android:name="com.example.MyTaskService" />

      在Java中开启这个服务

    Intent service = new Intent(getApplicationContext(), MyTaskService.class);
    Bundle bundle = new Bundle();
    
    bundle.putString("foo", "bar");
    service.putExtras(bundle);
    
    getApplicationContext().startService(service);

    警告

    1. 默认情况下,当app前台运行时,开启这个服务会导致app崩溃。这是为了防止app在展示界面的同时运行大量的后台工作,可以通过第四个参数来改变这种行为(默认为false,不允许任务在前台运行)
    2. 如果从广播接收者中开启服务,必须保证在onReceive结束前调用HeadlessJsTaskService.aquireWakeLockNow()

    例子

      这是一个可以响应网络连接变化的例子。首先在清单文件中配置广播接收者

    <receiver android:name=".NetworkChangeReceiver" >
      <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
      </intent-filter>
    </receiver>

      广播接收者在onReceive中处理广播,可以在这里检查app是否运行在前台:

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

    实践

       测试发现必须要多加一个权限:

    <uses-permission android:name="android.permission.WAKE_LOCK"/>

      对于以下代码:

    module.exports = async (taskData) => {
        await getData()
        await getData()
        await getData()
        await getData()
        await getData()
        await getData()
    };
    
    function getData(){
        return new Promise((resolve)=>{
            setTimeout(()=>{
                console.log("get data from server")
                resolve(1)
            },5000)
        });
    }

      当设置允许运行在前台时(allowedInForeground=true),前台或者后台开启服务都没问题,只是只要app进入后台,以上的代码就会被暂停,恢复前后后继续执行。

      当不允许前台运行时,前台开启服务则闪退,后台开启不会。后台开启后,仅仅执行了一个promise,就暂停了,恢复前台后剩余的代码继续执行,再次进入后台,则代码暂停,恢复前后剩余代码继续执行。

      以上运行的环境是夜神模拟器,还没到真机上测试。

  • 相关阅读:
    WPF 前台处理绑定字段
    DataBinding?资料绑定? #4绑定表达式原来可以这样用?(DataSet / DataReader)
    DataBinding?资料绑定? #7 伤脑筋的 GridView加总、小计(原来如此 / 范例下载)
    实战ASP.NET MVC 1.0 #3,新增一笔资料(Create / Add)
    实战ASP.NET MVC 1.0 #1,我的第一支MVC程序,展现所有数据(主细表的Master)
    ASP.NET MVC与Web Form的使用时机?
    实战ASP.NET MVC 2.0 #5,删除一笔记录
    DataBinding?资料绑定? #3以DropDownList为例
    DataBinding?资料绑定? #5绑定表达式 与 ListView的HyperLink(超级链接)
    DataBinding?资料绑定? #6 伤脑筋的 GridView加总、小计(Question)
  • 原文地址:https://www.cnblogs.com/hellohello/p/8323919.html
Copyright © 2011-2022 走看看