react-native-code-push在Android上的更新流程

2025 新版 RN 热更新(CodePush版)实战指南:从私有化部署到渐进式发布 本文详细介绍了2025新版RN热更新(CodePush版)的实战指南,涵盖私有化部署和渐进式发布策略。通过CodePush技术,开发者可以绕过应用商店审核,快速修复线上问题,提升效率。文章还提供了服务器选型、客户端集成及高级技巧等实用内容,帮助开发者掌握热更新的核心要点。 阅读详情

热更新

CodePush 是微软提供的一套用于热更新 React Native 和 Cordova 应用的服务。
CodePush 是提供给 React Native 和 Cordova 开发者直接部署移动应用更新给用户设备的云服务。CodePush 作为一个中央仓库,开发者可以推送更新 (JS, HTML, CSS and images),应用可以从客户端 SDK 里面查询更新。CodePush 可以让应用有更多的可确定性,也可以让你直接接触用户群。在修复一些小问题和添加新特性的时候,不需要经过二进制打包,可以直接推送代码进行实时更新。

CodePush 可以进行实时的推送代码更新:

  • 直接对用户部署代码更新
  • 管理 Alpha,Beta 和生产环境应用
  • 支持 React Native 和 Cordova
  • 支持JavaScript 文件与图片资源的更新

CodePush开源了react-native版本,react-native-code-push托管在GitHub上。

具体关于CodePush的部署及安装,本文不阐释,可自行搜索网络资源,本文是基于自己部署的Code Push服务器进行Android及iOS应用的热更新,已稳定运行超过2年。

 

Android code-push配置流程

(1)react native 的package.json的 react-native-code-push: "^5.7.0" ;

(2)Android代码中需要把对应的key配置好,我这直接在build.gradle上把配置,这样的好处在于debug与release上自动切换,避免犯错;

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "SIGN_CHECK", "true"
            buildConfigField "String", "CODE_PUSH_KEY", '"配置你的key"'
            buildConfigField "boolean", "IS_CODE_PUSH", "true"
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "SIGN_CHECK", "false"
            buildConfigField "String", "CODE_PUSH_KEY", '"配置你的key"'
            buildConfigField "boolean", "IS_CODE_PUSH", "true"
            signingConfig signingConfigs.release
        }
    }

(3)将react-native-code-push link进来,建议手动配置,直接运行命令的话不保证正常,而且容易出小毛病,setting.gradle配置如下:

rootProject.name='Test'
include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
include ':app'

(4)新建一个React native的容器,我这直接在TestActivity.java上操作,具体如下:

public class TestActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
 private ReactRootView mReactRootView;
 private ReactInstanceManager mReactInstanceManager;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        ReactInstanceManagerBuilder mReactInstanceManagerBuilder = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new CodePush(
                        BuildConfig.CODE_PUSH_KEY,
                        getApplicationContext(),
                        BuildConfig.DEBUG,
                        "填上你的热更新服务器地址"))
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED);
        //根据实际build.gradle配置是否在测试与生产环境下开启热更新,开启了则将JS文件采用CodePush的
        if (BuildConfig.IS_CODE_PUSH) {
            mReactInstanceManagerBuilder.setJSBundleFile(CodePush.getJSBundleFile());
        }
        mReactInstanceManager = mReactInstanceManagerBuilder.build();
        // 注意这里的MyReactNativeApp必须对应“index.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "Test", null);
        setContentView(mReactRootView);

    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
            mReactInstanceManager.destroy();
            mReactInstanceManager = null;
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }

   @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

}

以上基本是Android的大致code-push配置流程,剩下的需要在js代码中添加code-push的调用了

(5)回到react native代码上,我们需要在打开APP时或者从后台重新返回到前台时进行检测热更新,具体的策略可自行调整,启动页如下Test.android.js:

import React, {Component} from 'react';
import {View,Text} from 'react-native';
import CodePush from "react-native-code-push";

let codePushOptions = {checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME};
type Props = {};

class Test extends Component<Props> {

    componentDidMount(): void {
        this.syncImmediate();
    }

    //如果有更新的提示
    syncImmediate = () => {
        let syncOption = {
            deploymentKey: '对应原生上的key,注意debug与release',
            updateDialog: false,
            mandatoryInstallMode: CodePush.InstallMode.IMMEDIATE,
            InstallMode: CodePush.InstallMode.IMMEDIATE,
            rollbackRetryOptions: {
                delayInHours: 1,//回滚后重试,1小时/次
                maxRetryAttempts: 24//回滚后重试,最大尝试24次
            }
        };
        CodePush.sync(syncOption, (status) => {
            console.log("CodePush = change " + JSON.stringify(status))
            switch (status) {
                case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
                    console.log("CodePushLabel DOWNLOADING_PACKAGE");
                    break;
                case CodePush.SyncStatus.INSTALLING_UPDATE:
                    console.log("CodePushLabel INSTALLING_UPDATE");
                    break;
                case CodePush.SyncStatus.UP_TO_DATE:
                case CodePush.SyncStatus.UPDATE_INSTALLED:
                    console.log("CodePushLabel " + CodePush.SyncStatus.UP_TO_DATE);
                    //存储当前热更新版本号
                    CodePush.getUpdateMetadata().then((localPackage) => {
                     
                        if (JSON.stringify(localPackage) !== '{}' && localPackage.hasOwnProperty('label')) {
                            console.log("CodePushLabel = " + localPackage.label + " failedInstall = " + localPackage.failedInstall);
                            //TODO存储操作
                        }
                    }).catch(e => {
                        console.log("CodePushLabel Err = " + e);
                    });
                    break;
                case CodePush.SyncStatus.SYNC_IN_PROGRESS:
                    console.log("CodePushLabel SYNC_IN_PROGRESS");
                    break;
                case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
                    console.log("CodePushLabel SYNC_IN_PROGRESS");
                    break;
            }
        }, (progress) => {
            console.log("CodePush = progress " + JSON.stringify(progress))
        }, (update) => {
            console.log("CodePush = update " + JSON.stringify(update))
        });
    };

    render() {
        return (
            <View>
                <Text>测试</Text>
            </View>
        );
    }

}

export default TestPage= CodePush(codePushOptions)(Test);

(6)运行热更新命令

//Staging为测试,Production为生产,Test-android中的Test为配置的项目名
code-push release-react Test-android android -d Staging-m true --des '1. 测试热更新' --t 1.0.0

Android热更新下载流程

在配置完后,我们可以进行手动debug查看具体code-push到底是怎么实现热更新下载

(1)在React native 挂载中,我们通过CodePush调用sync方法来实现检测更新,CodePush.js

// This function allows only one syncInternal operation to proceed at any given time.
// Parallel calls to sync() while one is ongoing yields CodePush.SyncStatus.SYNC_IN_PROGRESS.
const sync = (() => {
  let syncInProgress = false;
  const setSyncCompleted = () => { syncInProgress = false; };

  return (options = {}, syncStatusChangeCallback, downloadProgressCallback, handleBinaryVersionMismatchCallback) => {
    let syncStatusCallbackWithTryCatch, downloadProgressCallbackWithTryCatch;
    if (typeof syncStatusChangeCallback === "function") {
      syncStatusCallbackWithTryCatch = (...args) => {
        try {
          syncStatusChangeCallback(...args);
        } catch (error) {
          log(`An error has occurred : ${error.stack}`);
        }
      }
    }

    if (typeof downloadProgressCallback === "function") {
      downloadProgressCallbackWithTryCatch = (...args) => {
        try {
          downloadProgressCallback(...args);
        } catch (error) {
          log(`An error has occurred: ${error.stack}`);
        }
      }
    }

    if (syncInProgress) {
      typeof syncStatusCallbackWithTryCatch === "function"
        ? syncStatusCallbackWithTryCatch(CodePush.SyncStatus.SYNC_IN_PROGRESS)
        : log("Sync already in progress.");
      return Promise.resolve(CodePush.SyncStatus.SYNC_IN_PROGRESS);
    }

    syncInProgress = true;
    const syncPromise = syncInternal(options, syncStatusCallbackWithTryCatch, downloadProgressCallbackWithTryCatch, handleBinaryVersionMismatchCallback);
    syncPromise
      .then(setSyncCompleted)
      .catch(setSyncCompleted);

    return syncPromise;
  };
})();

从源码我们继续进入到syncInternal方法内,在CodePush.js文件410行,先将正在等待的更新全部移除

 await CodePush.notifyApplicationReady();

Android源码可以对应找到CodePushNativeModule.java内的notifyApplicationReady方法,因为js上await,所以需要等待Android这边处理完后才往下进行

    @ReactMethod
    public void notifyApplicationReady(Promise promise) {
        try {
            mSettingsManager.removePendingUpdate();
            promise.resolve("");
        } catch(CodePushUnknownException e) {
            CodePushUtils.log(e);
            promise.reject(e);
        }
    }

(2)清除完后,js通过code-push包下script的acquisition-sdk.js进行与服务器的版本对比,当本地热更新版本小于服务器的热更新版本时,返回需要下载的信息

   AcquisitionManager.prototype.queryUpdateWithCurrentPackage = function (currentPackage, callback) {
            ...
            try {
                var responseObject = JSON.parse(response.body);
                var updateInfo = responseObject.update_info;
            }
            catch (error) {
                callback(error, /*remotePackage=*/ null);
                return;
            }
            ...
        });
    };

(3)下载热更新包,我们可以打开Android中的code-push源码,找到CodePushUpdateManager.java的downloadPackage方法,

其中热更新下载到本地的路径为/data/user/0包名/files/CodePush/热更新包哈希值/,通过Android studio的Device File Explorer可以看到,下载下来的是一个压缩包

代码往下走,可以找到CodePushUpdateManager.java的downloadPackage方法里,将下载到的压缩包进行解压,得到一个unzipped的文件夹,然后通过刚才的热更新包哈希进行新建一个文件夹,将unzipped的内容复制到该文件夹下,然后删除unzipped文件夹,为下一次热更新做准备,下载整体流程基本如上,理解来不难,可以看到热更新包解压后的内容包括图片资源、bundle文件,也就是js代码,

 

Android热更新安装流程

前面说明热更新的下载,既然热更新的文件我们都下载下来了,剩下的就是将bundle与资源文件重新指向到新下载的热更新文件下。接下来,我们继续来分析源码,查看安装更新的流程。

(1)继续回到CodePushUpdateManager.java的downloadPackage方法里,这里有一个比较有意思的地方,可以看到在248行代码里,有这么一段,是不是说明咱们热更新也可以支持增量更新,而不用全量更新呢?有待实验~

     if (isDiffUpdate) {
        CodePushUtils.log("Applying diff update.");
     } else {
        CodePushUtils.log("Applying full update.");
     }

在方法最后一段,CodePushUtils.writeJsonToFile(updatePackage, newUpdateMetadataPath),目的是将热更新包的内容更新本地,作为下一次的热更新版本对比。

(2)回到CodePush.js的syncInternal方法内,接下来进行安装流程,

   await localPackage.install(resolvedInstallMode, syncOptions.minimumBackgroundDuration, () => {
        syncStatusChangeCallback(CodePush.SyncStatus.UPDATE_INSTALLED);
      });

在安装前会检测是否文件下载失败,如果失败了,将会在SettingsManager.java 的 saveFailedUpdate 方法以SharedPreferences记录下来具体哪些资源下载失败。

回到CodePushNativeModule.java中的installUpdate方法,我们在起初时设置的更新安装模式为CodePushInstallMode.ON_NEXT_RESUME,将在下次onResume时进行安装,源码中可以看到通过Runnable接口中调用loadBundle方法。

(3)在loadBundle方法里,可以看到将更新下来的bundle与资源文件路径重新加载,从而达到热更新的目的。

    // Use reflection to find and set the appropriate fields on ReactInstanceManager. See #556 for a proposal for a less brittle way
    // to approach this.
    private void setJSBundle(ReactInstanceManager instanceManager, String latestJSBundleFile) throws IllegalAccessException {
        try {
            JSBundleLoader latestJSBundleLoader;
            if (latestJSBundleFile.toLowerCase().startsWith("assets://")) {
                latestJSBundleLoader = JSBundleLoader.createAssetLoader(getReactApplicationContext(), latestJSBundleFile, false);
            } else {
                latestJSBundleLoader = JSBundleLoader.createFileLoader(latestJSBundleFile);
            }

            Field bundleLoaderField = instanceManager.getClass().getDeclaredField("mBundleLoader");
            bundleLoaderField.setAccessible(true);
            bundleLoaderField.set(instanceManager, latestJSBundleLoader);
        } catch (Exception e) {
            CodePushUtils.log("Unable to set JSBundle - CodePush may not support this version of React Native");
            throw new IllegalAccessException("Could not setJSBundle");
        }
    }

(4)在loadBundle方法里,调用ReactInstanceManager的recreateReactContextInBackground重新创建React native的上下文,如果在重新加载过程中还没完成,则判断是否需要进行回滚操作,CodePush.java中initializeUpdateAfterRestart方法

 void initializeUpdateAfterRestart() {
        // Reset the state which indicates that
        // the app was just freshly updated.
        mDidUpdate = false;

        JSONObject pendingUpdate = mSettingsManager.getPendingUpdate();
        if (pendingUpdate != null) {
            JSONObject packageMetadata = this.mUpdateManager.getCurrentPackage();
            if (packageMetadata == null || !isPackageBundleLatest(packageMetadata) && hasBinaryVersionChanged(packageMetadata)) {
                CodePushUtils.log("Skipping initializeUpdateAfterRestart(), binary version is newer");
                return;
            }

            try {
                boolean updateIsLoading = pendingUpdate.getBoolean(CodePushConstants.PENDING_UPDATE_IS_LOADING_KEY);
                if (updateIsLoading) {
                    // Pending update was initialized, but notifyApplicationReady was not called.
                    // Therefore, deduce that it is a broken update and rollback.
                    CodePushUtils.log("Update did not finish loading the last time, rolling back to a previous version.");
                    sNeedToReportRollback = true;
                    rollbackPackage();
                } else {
                    // There is in fact a new update running for the first
                    // time, so update the local state to ensure the client knows.
                    mDidUpdate = true;

                    // Mark that we tried to initialize the new update, so that if it crashes,
                    // we will know that we need to rollback when the app next starts.
                    mSettingsManager.savePendingUpdate(pendingUpdate.getString(CodePushConstants.PENDING_UPDATE_HASH_KEY),
                            /* isLoading */true);
                }
            } catch (JSONException e) {
                // Should not happen.
                throw new CodePushUnknownException("Unable to read pending update metadata stored in SharedPreferences", e);
            }
        }
    }

更新完成后,返回CodePush.SyncStatus.UPDATE_INSTALLED标识

至此,code-push在Android上的热更新流程如上!

 

结语

简单的介绍了code-push在Android上热更新的应用。欢迎大家拍砖点赞分析收藏,谢谢大家。

 

 

 

 

 

 

 

 

 

 

 

 

React Native 实现热更新方案CodePush过程中遇到的问题 ( 搭建自己的CodePush服务器 ) 前言 CodePush官方: https://github.com/Microsoft/react-native-code-push 自搭建CodePushServer: https://github.com/lisong/code-push-server 参考文章: https://www.jianshu.com/p/417a165ca9d7 https://github.com/crazyco... 阅读详情

相关推荐

CodePush优化之减小更新包体积

欢迎大家关注【跨平台开发那些事】公众号,定期推送跨平台开发技术实践。 述 还有 10 天就要迎来 2019 新年,感慨 18 年过的好快,恍恍惚惚。2018 年经历了很多,人生最重要的事情,很开心。闲余时间浏览了这一年写过的博客,9 篇相对 17 年少了很多。时间不等人,什么事还是要提前计划往前做。本来是要等新年再和大家分享新的内容,回头看看还是以整数结尾这一年,也算欣慰。 这篇博...

... 1518

RN软件版本更新,安装react-native-code-push后运行报错

关于版本更新步骤参考 https://cloud.tencent.com/developer/article/1191478 一、参考 React Native 0.60及以上版本插件安装与配置(安卓)https://github.com/microsoft/react-native-code-push/blob/master/docs/setup-android.md 二、我的环境及安装版本 node-v14.17.6 “react-native”: “0.65.1”, “react-native-cod

2931

react-native-code-push, 为CodePush响应本机模块.zip

react-native-code-push, 为CodePush响应本机模块 针对CodePush响应本机 MODULE注意:这个自述文件只与我们的插件的最新版本相关。 如果你使用的是旧版本,请在我们的GitHub repo 上找到相关标签,以便查看该特定版本的文档。 这个插件为 CodePush服

ReactNative使用codepush

一、获取版本信息 codePush.getUpdateMetadata(codePush.UpdateState.LATEST).then((update) => { if (update) { this.props.authLoadingMobx.setPackageInfo(update.appVersion+"@"+update.label); ...

kris1122的博客 577

HMC7044芯片模拟SPI配置

摘要: HMC7044是一款高性能双环路整数N分频抖动衰减器,支持SPI接口配置,适用于高速数据转换器时钟系统。该芯片采用双PLL级联架构,具有14路可配置输出,可满足GSM/LTE基站设计需求。SPI接口采用3线模式(SLEN/SCLK/SDATA),支持24位寄存器读写(13位地址+8位数据)。驱动实现基于Zynq EMIO模拟SPI,提供初始化、数据传输及寄存器配置功能,支持三线制工作模式和多种时钟参数设置。

toonyhe的博客 1094

地震勘探中的频谱分析:从基础到应用

本文深入探讨了地震勘探中的频谱分析技术,从基础原理到实际应用。通过傅里叶变换等工具,频谱分析能有效识别不同地震波的频率特征,指导数据采集和处理。文章结合油田勘探案例,展示了如何利用振幅谱和相位谱提升信噪比,并介绍了智能滤波等前沿技术在地震数据处理中的应用。

weixin_42557830的博客 406

React native 热更新之CodePushy

最近学习了一下facebook出的一个react native 有点类始于h5,是一款基于javaScript 语法及react框架的一门新生跨平台的开源技术框架,能同时在android 端和ios端同时运行,可以实现一次学习,随处编写,虽然目前还没有出1.0版本,但是这款框架还是有其优势的,具体的环境变量搭建初始化项目可以去RN官网去看一下,今天写这篇文章的主要目的是巩固一下新学的知识点,做一些

tianruizhong的博客 496

端侧视觉赋能手游自动化:YOLOv8+NCNN实现低风险挂机与广告拦截

本文提出一种基于端侧AI的移动游戏自动化解决方案,采用YOLOv8目标检测和NCNN推理框架,结合AutoJS实现"感知-决策-执行"闭环。方案通过轻量化模型训练、多分辨率适配和行为拟态优化,解决了传统脚本的适配性和风控问题。关键技术包括:构建游戏专属数据集、模型量化优化、广告拦截和挂机功能实现,具有本地运行、安全稳定等特点,为个人开发者提供了一套完整的自动化开发框架。

milk416666的博客 1263

CodePush 资源更新原理及资源自动回滚的 bug 解析

1. 使用者使用如下方法调用 CodePush 的 sync 方法 RnCachePage.js import React, {Component} from 'react'; import { View, } from 'react-native'; import codePush from "react-native-code-push"; // 引入code-push //...

满地星辰的博客 4928

42、InfiniBand技术详解:QP状态机、操作及错误处理

本文深入解析InfiniBand技术中的核心组件QP(Queue Pair)状态机、工作请求处理机制、支持的操作类型及错误处理策略。详细介绍了QP的创建与状态转换流程,包括INIT、RTR、RTS等关键状态,并提供了状态修改的代码示例。文章还探讨了工作请求的发布、资源使用限制、围栏机制以及重试和RNR流程,帮助开发者理解通信可靠性保障机制。此外,涵盖了多播组的应用场景与API使用方法,并对比了用户空间与内核级RDMA API的调用差异,最后给出了实践建议和常见问题解答,为构建高性能分布式系统提供技术指导。

oauth7security的博客 131

MATLAB离线附加功能包下载与安装教程

本文介绍如何下载与安装MATLAB离线附加功能包,便于大家更加高效的使用MATLAB。

加斯顿工程师的博客 1万+

native react 更新机制_react-native热更新全方位讲解

最近在研究热更新技术,看了网上各个大佬的博客,整体流程上总是卡壳。跳了几天坑,刚刚终于把简单的热更新流程跑通,现在也正在一边学习更新,一边整理资料,在此篇博客上记录操作流程,希望我的实践能帮助各位同行少走弯路,快速掌握热更新技术。热更新流程图热更新步骤1、热更新服务器部署2、客户端配置3、客户端热更新代码4、打包最新代码5、推送你的新包到客户端6、疑问Q: “苹果应用商店和android应用商店允...

weixin_40001967的博客 807

HFSS实战项目——GPS北斗双模微带天线

本文设计了一款方形圆极化微带天线应用于北斗B1和GPSL1频段,满足高增益、低VSWR、适当方向图等要求。设计中心频率为1568MHz,介质板采用厚度h=1.6mm的Arlon AD450(tm)板,相对介电常数为4.5,采用探针馈电。

2401_87464239的博客 1767

‘react-native热更新‘

前言 最新做了app的业务, 由于之前没有做过热更新导致每次更新都要去更新app, 特别麻烦. 所以花了点时间, 接入了热更新的功能。 我选择的是react-native-code-push的npm包。 接入与安装 首先进行安装 npm || yarn react-native link react-native-code-push 接入时选择跟自己的react-native匹配的react-native-code-push进行接入。 react-native-code-push接入 全局

m0_65466108的博客 344

LDRA Testbed软件静态分析_常见问题及处理

通过前面的几篇文章,LDRA Testbed软件静态分析的内容基本讲解完了,本篇文章将针对使用Testbed进行软件静态分析的常见问题进行介绍。 到此为止,LDRA Testbed软件静态分析的内容已经全部讲完,如果有问题,欢迎私信提问(不经常登录,回复可能不及时,见谅)。下一篇文章将开始讲解如何使用Testbed进行单元测试。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 2585

HyperLynx(十九)DDR(二)DDR的地址仿真

(5)设置水平标尺为2ns/div,垂直标尺为500mV/div,如果有必要,可以通过多次仿真,得到一个更加理想的结果。此外,还可以看到信号在高低电平切换时,反射波形基本趋于平缓,许多大的反射切换边缘已减小,这给了我们更大的定时裕量。如果这些DIMM是缓冲过的,则4个DIMM通道是可行的,但因为这是一个无缓冲DIMM,(20)在编辑传输线对话框中,选择“Values”选项卡,改变传输线长度为3in,具体设置如图所示,单击“确定”按钮。(17)为了增加电压摆幅,选择一个比原来的47Ω小的电阻。

小幽余生不加糖 4257

React Native项目自动化打包发布

今天这篇文章的目的是在rn项目的构建,并不会涉及到rn框架或者使用的讲解,说起构建,特别是前端构建大家应该很快会想到webpack、Grunt、 Gulp等。而这些工具在rn项目中就显得有些鸡肋。所以...

weixin_39037804的博客 443

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

微软的React Native热更新

官方相关资源: code push github:&nbsp;https://github.com/Microsoft/react-native-code-push code push官网:http://microsoft.github.io/code-push/ code push cli手册:h...

闫瑞锋的博客 638

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

React Native热更新实战:CodePush私有化部署全流程(含常见问题解决)

本文详细介绍了React Native应用热更新方案CodePush的私有化部署全流程。通过自建服务,企业可完全掌控更新流程与数据安全,尤其适合金融、医疗等对合规性要求高的场景。文章涵盖从架构选型、服务器环境搭建(MySQL、Node.js、Nginx)、客户端集成配置,到CLI工具使用、生产环境运维及安全加固的完整实战指南,并提供了常见问题解决方案。

weixin_29005499的博客 353

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2021了React Native热更新怎么搞(react-native-code-push,Android,iOS)

RN的热更方案也在不断发展,目前RN中文官网上推的是pushy,然而是收费的,对于小企业就比较劝退了。另一个比较成熟的方案是react-native-code-push,本文将基于CodePush集成热更新。 关于热更新的特性,想要的ta都有 粗略阅读文档,CodePush的特性还是非常全的,涵盖一般场景能设想到的各种问题。 Q:热更支持到什么程度? A:JS的变动,Image等组件的source引用都可以热更。遗憾的是,CodePush是bundle的更新,意味着原生代码的变动不能通过热更解决。对于小问题

Synaric的专栏 4775

react-native-code-push热更新

code-push账号 1.安装Code-Push的命令行工具: npm install -g code-push-cli 2.注册 code-push register 3.若已经注册过,则直接登录 code-push login 运行之后,会在浏览器中打开一个返回token的页面 复制token值到控制台登录 4.创建应用 code-push app add <...

Bearin的博客 624

react-native code-push 热更新

1. 安装 CodePush CLI npm install -g code-push-cli 复制代码2. 注册 CodePush账号 code-push register 复制代码 ⚠️ 这里会弹出一个网页选择 github 授权, 注册成功后会得到一个 key , 将 key 复制到终端回车 3. 添加 ios 平台应用 code-push app add rebooking-ios io...

weixin_34228387的博客 316

【React-native】轻松从零搭建微软Code-Push热更新

总体步骤: 前提:需要 mac 电脑(iOS需要,仅安卓Win亦可),RN iOS/android 环境搭建好,服务器一台(最好linux),mysql 数据库以及 git 和 npm 环境。 搭建服务器,下载code-push项目,npm install安装,配置数据库,生成数据库表。 打开阿里云3000端口,运行测试。 本地安装code-push-cli,获取token,推送应...

冯一朔 - 不想当CTO的程序员不是一个好哲学家 1206

深入理解lisong/code-push-server在React Native热更新中的应用

在移动应用开发中,热更新(Hot Update)是一项非常重要的技术,它允许开发者在不重新发布应用商店版本的情况下,动态更新应用内容。本文将详细介绍如何利用lisong/code-push-server项目为React Native应用实现高效可靠的热更新方案。 ## 热更新基础概念 ### 什么是热更新? 热更新是指在不通过应用商店审核流程的情况下,直接向用户设备推送应用更新的技术。这种技...

gitblog_00924的博客 522

React Native之code-push的热更新(ios android)

React Native之code-push的热更新(ios android) React Native支持大家用React Native技术开发APP,并打包生成一个APP。在动态更新方面React Native只是提供了动态更新的基础,对将应用部署到哪里,如何进行动态更新并没有支持的那么完善。好在微软开发了CodePush,填补React Native 应用在动态更新方面的空白。C...

LeoStarry2014的博客 371

React Native 使用Code-Push 更新APP

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl

zhuangchuming的博客 753
上一篇: 热修复:关于Tinker在Android9.0机器上合成失败的解决方案
下一篇: react native 网络请求工具类的封装
JosonChou
博客等级 码龄11年 8粉丝 18原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值