native放回进入后台 react

2017-05-09 14:43:39 jiejiegua 阅读数 6040
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    0课时 0分钟 71人学习 田果果
    免费试看

     在android app 的开发的开发过程中,我们需要监听android的返回键,退出active界面。

    有时为了,能够给用户更好的体验,需要app退出界面后,app在后台运行。(当然这可能还需要实现 常驻内存,可以点击这里查看 常驻内存实现

   react native 提供backAndroid api,可以我们使用后发现。该api的退出,是结束进程,也就是完全退出。

 于是查看该api,发现backAndroid api在ReactActivity里面的实现,最后默认会调用 invokeDefaultOnBackPressed 这个方法。

  那我们想要实现在根路由里面,退出到后台运行,而不是关闭路由。该怎么解决呢?

 这里我们只需在MainActivity里面重写invokeDefaultOnBackPressed方法就行。

为了方便大家copy,我贴出重写后的代码。我想对于react native android 着急的同学可以看看。

public void invokeDefaultOnBackPressed() {
    PackageManager pm = getPackageManager();
    ResolveInfo homeInfo =
     pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME), 0);
     ActivityInfo ai = homeInfo.activityInfo;
    Intent startIntent = new Intent(Intent.ACTION_MAIN);
    startIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    startIntent.setComponent(new ComponentName(ai.packageName, ai.name));
    startActivity(startIntent);
}
具体思路就是在退出前,将当期的Intent 保存。

或者这样重写invokeDefaultOnBackPressed方法,当然这样重写的话,只会在根路由退出才起作用

public void invokeDefaultOnBackPressed() {
    moveTaskToBack(false);
}



当然要实现根路由退出你得在根路由实现以下方法。 注意backandroid 返回false 会结束应用运行,所以最后返回true

removeBackAndroidListener=()=> {
    if (Platform.OS === 'android') {
        BackAndroid.removeEventListener('hardwareBackPress', () => {
        });
    }
};
addBackAndroidListener=(navigator)=> {
    if (Platform.OS === 'android') {
        BackAndroid.addEventListener('hardwareBackPress',() => {
            return this._onBackAndroid(navigator);
        });
    }
};

_onBackAndroid=(navigator)=> {
    if (!navigator) return false;
    const routers = navigator.getCurrentRoutes();
    // 当前页面不为root页面时的处理
    if (routers.length > 1) {
        const top = routers[routers.length - 1];
        if (top.ignoreBack || top.component.ignoreBack) {
            // 路由或组件上决定这个界面忽略back            return true;
        }
        const handleBack = top.handleBack || top.component.handleBack;
        if (handleBack) {
            // 路由或组件上决定这个界面自行处理back            return handleBack();
        }
        // 默认行为: 退出当前界面。
        navigator.pop();
        return true;
    }
    // 当前页面为root页面时的处理
    if (this.lastBackPressed ) {
        //最后退出到后台运行。
        BackAndroid.exitApp();
        return true;
    }
    this.lastBackPressed = Date.now();
   // ToastAndroid.show(I18n.t('text.doubleAgain'),ToastAndroid.SHORT);
    return true;
};


2018-07-04 14:32:53 xtyzmnchen 阅读数 3801
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    0课时 0分钟 71人学习 田果果
    免费试看

react native 中提供了一个 AppStates 这样一个api 给我们使用 。

官方解释:

AppState能告诉你应用当前是在前台还是在后台,并且能在状态变化的时候通知你。

AppState通常在处理推送通知的时候用来决定内容和对应的行为

状态:

active - 应用正在前台运行
background - 应用正在后台运行。用户既可能在别的应用中,也可能在桌面。
inactive - 这是一个过渡状态,不会在正常的React Native应用中出现


方法 :

static addEventListener(type: string, handler: Function) 

添加一个监听函数,用于监听应用状态的变化。type参数应填change 。

static removeEventListener(type: string, handler: Function) 

移除一个监听函数。type参数应填change。


注意:

要获取当前的状态,你可以使用AppState.currentState,这个变量会一直保持更新。不过在启动的过程中,currentState可能为null,直到AppState从原生代码得到通知为止


应用:

  1. export default class HomePager extends Component {
  2. constructor(props) {
  3. super(props);
  4. //设置一个标记,表示从后台进入前台的时候,处理其他逻辑
  5. this.flage = false
  6. }
  7. componentDidMount(){
  8. AppState.addEventListener('change',this._handleAppStateChange);
  9. }
  10. _handleAppStateChange = (nextAppState)=>{
  11. if (nextAppState!= null && nextAppState === 'active') {
  12. //如果是true ,表示从后台进入了前台 ,请求数据,刷新页面。或者做其他的逻辑
  13. if (this.flage) {
  14. //这里的逻辑表示 ,第一次进入前台的时候 ,不会进入这个判断语句中。
  15. // 因为初始化的时候是false ,当进入后台的时候 ,flag才是true ,
  16. // 当第二次进入前台的时候 ,这里就是true ,就走进来了。
  17. //测试通过
  18. // alert("从后台进入前台");
  19. // 这个地方进行网络请求等其他逻辑。
  20. }
  21. this.flage = false ;
  22. }else if(nextAppState != null && nextAppState === 'background'){
  23. this.flage = true;
  24. }
  25. }
  26. componentWillUnmount() {
  27. AppState.removeEventListener('change', this._handleAppStateChange);
  28. }
  29. }
完美测试!!!!!!!!!
2018-03-25 13:11:52 qq_33323251 阅读数 4795
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    0课时 0分钟 71人学习 田果果
    免费试看

react native Android端保持APP后台运行--封装 Headless JS

前些日子在做后台下载时踩了后台运行这个大坑,RN官网文档上面在安卓上提供了Headless JS方法,iOS上暂时没有提供后台运行的方法,不过众所周知,官网上面的文档实在是... 于是在全网一通好搜,终于让我发现了一个将Headless JS封装好了的第三方组件:

react-native-background-job

下面介绍使用方法: 

安装

yarn add react-native-background-job

或者

npm install react-native-background-job --save

然后运行:

react-native link react-native-background-job

使用

1. 需在你所需要后台运行的组件内部--类的上方注册后台下载事件

import BackgroundJob from 'react-native-background-job';
//当在安卓下时,开启后台模式,注册后台事件
if(Platform.OS === 'android'){
    const backgroundJob = {
        jobKey: "backgroundDownloadTask",
        job: () => {}
    };
    BackgroundJob.register(backgroundJob);
}

下面才开始是你的类的代码,注册后台事件一定要在类之前:

class BackgroundTask extends PureComponent {}

2. 注册的后台运行事件是全局的,你可以在任何文件的任何地方启动后台运行,不过在其他页面启动后台运行事件需要在其页面导入BackgroundJob:

import BackgroundJob from 'react-native-background-job';

启动后台运行:

BackgroundJob.schedule({
    jobKey: "backgroundDownloadTask",//后台运行任务的key
    period: 500,                     //任务执行周期
    exact: true,                     //安排一个作业在提供的时间段内准确执行
    allowWhileIdle: true,            //允许计划作业在睡眠模式下执行
    allowExecutionInForeground: true,//允许任务在前台执行
});
具体属性请移步 react-native-background-job



2018-07-24 11:49:53 u011215669 阅读数 5860
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    0课时 0分钟 71人学习 田果果
    免费试看

使应用处于后台时运行JavaScript的后台任务。

即使应用程序已关闭,任务也会运行,默认情况下,也会在重新启动后继续存在。

这个库依赖于React Native的HeadlessJS ,目前只支持Android。

在本机端,它使用Firebase JobDispatcherAlarmManager

  • Firebase JobDispatcher(默认值):无法准确计划任务,并且根据Android API版本允许不同的period段。 FirebaseJobDispatcher是最节省电池效率的后向兼容调度后台任务的方式。

  • AlarmManager通过将exact设置为true :简单的propriatery实现,仅在测试时使用。 它只关心按时执行,所有其他参数都被忽略 - 重启时不会保留任务。

要求

RN 0.36+
Android API 16+ 

支持的平台

仅Android

安装


  • 下载
$ yarn add react-native-background-job
or
$ npm install react-native-background-job --save
  • 自动安装
$ react-native link react-native-background-job
  • 手动安装
  1. 打开android/app/src/main/java/[...]/MainActivity.java
    添加import com.pilloxa.backgroundjob.BackgroundJobPackage;到文件顶部的导入
    new BackgroundJobPackage()添加到MainApplication.javagetPackages()方法返回的列表中

  2. 将以下行追加到android/settings.gradle

          include ':react-native-background-job' 
          project(':react-native-background-job').projectDir = new  File(rootProject.projectDir, '../node_modules/react-native-background-job/android') 
    
  3. 在android/app/build.gradle的依赖项块中插入以下行,并将minSdkVersion置为21:

      compile project(':react-native-background-job') 

用法


每次React Native启动时都必须注册任务,这是使用register函数完成的。 由于HeadlessJS不安装任何组件,因此register函数必须在任何类定义之外运行。

注册任务并不意味着任务已被调度,它只是通知React Native该job函数应该绑定到此jobKey。 然后使用schedule功能安排任务。 默认情况下,当应用程序位于前台时,任务不会触发 。 这是因为任务是在唯一的JavaScript线程上运行的,如果在app处于前台时运行任务,它将冻结应用程序。 通过将allowExecutionInForeground设置为true可以允许此行为。 建议不要使用它,但快速工作应该没问题。

API


register

注册任务和应该运行的功能。

必须在React Native的每次初始化时运行,并且必须在全局范围内运行,而不是在任何组件生命周期方法中运行。 仅注册任务不会安排任务。 必须按schedule才能开始运行。

参数

obj 对象
    obj.jobKey string任务的唯一键
    obj.job 函数将运行的JS函数 

例子

import BackgroundJob from 'react-native-background-job';
 
const backgroundJob = {
 jobKey: "myJob",
 job: () => console.log("Running in background")
};
 
BackgroundJob.register(backgroundJob);

schedule

安排一份新工作。

这只需要运行一次,而在每次初始化React Native时都必须运行register 。

参数

obj 对象
    obj.jobKey string用于注册的任务的唯一键,用于在后续阶段取消。
    obj.timeout number无论任务是否已完成,都应终止React实例的时间(以毫秒为单位)。 (可选,默认2000 )
    obj.period number运行任务的频率(以ms为单位)。 这个数字不准确,Android可能会修改它以节省电池。 注意:对于Android> N,最小值为900 0000(15分钟)。 (可选,默认900000 )
    obj.persist boolean如果任务应该在设备重启时保持obj.persist 。 (可选,默认为true )
    obj.override boolean此任务是否应使用相同的键替换预先存在的任务。 (可选,默认为true )
    obj.networkType number仅针对特定网络要求运行。 (可选,默认NETWORK_TYPE_NONE )
    obj.requiresCharging boolean仅在设备正在充电时运行任务(未被Android N设备预备) docs (可选,默认为false )
    obj.requiresDeviceIdle boolean仅在设备空闲时运行任务(未被Android N设备预备) docs (可选,默认为false )
    obj.exact boolean安排在提供的时间段内准确触发的任务。 请注意,这不是节能的做事方式。 (可选,默认为false )
    obj.allowWhileIdle boolean允许预定任务在打盹模式下执行。 (可选,默认为false )
    obj.allowExecutionInForeground boolean即使应用程序位于前台,也允许执行预定任务。 仅用于短期任务。 (可选,默认为false ) 

例子

import BackgroundJob from 'react-native-background-job';
 
const backgroundJob = {
 jobKey: "myJob",
 job: () => console.log("Running in background")
};
 
BackgroundJob.register(backgroundJob);
 
var backgroundSchedule = {
 jobKey: "myJob",
}
 
BackgroundJob.schedule(backgroundSchedule);

cancel

取消特定的工作

参数

obj 对象
    obj.jobKey string作业的唯一键 

例子

 import BackgroundJob from 'react-native-background-job';
 BackgroundJob.cancel({jobKey: 'myJob'});

cancelAll

取消所有预定作业

例子

import BackgroundJob from 'react-native-background-job';
 
BackgroundJob.setGlobalWarnings(false);

setGlobalWarnings

设置全局警告级别

参数

warn 布尔 

例子

  import BackgroundJob from 'react-native-background-job'; 
  BackgroundJob.setGlobalWarnings(false); 

isAppIgnoringBatteryOptimization

检查应用程序是否使用Doze优化电池,返回布尔值。

参数

callback从Android模块收到结果后,使用相应的参数callback 回调 。 

例子

import BackgroundJob from 'react-native-background-job'; 
BackgroundJob.isAppIgnoringBatteryOptimisation((error,ignoringOptimization)=>{});

参考链接

2019-07-18 17:09:32 qq_40054213 阅读数 371
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    0课时 0分钟 71人学习 田果果
    免费试看

react-native-sound

安装:

         1、npm install react-native-sound

         2、react-native link react-native-sound //建议使用手动link

gihub地址https://github.com/zmxv/react-native-sound

使用:

        引入:import Sound from 'react-native-sound'

let sound= new Sound('sound.mp3', Sound.MAIN_BUNDLE, (error) => {
  if (error) {
    console.log('failed to load the sound', error);
    return;
  }
  whoosh.play((success) => {
    if (success) {
      console.log('successfully');
    } else {
      console.log('errors');
    }
  });
});

设置:

1、play();//播放

2、stop();//停止

3、release();//释放

4、setSpeakerPhoneOn();//调整听筒和扬声器

5、loop();//循环播放