React-native 热更新(1) 脚本与图片更新+图片加载源码分析 android部分

本文详细介绍了React Native应用的热更新,包括脚本更新和图片更新。脚本更新通过bundle文件或补丁文件实现,图片更新则深入源码分析加载过程,涉及resolveAssetSource和AssetSourceResolver等组件,探讨了增量更新的实现策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 react-native热更新分两个方面,脚本更新和图片更新,我们将在图片更新的地方分析一下图片加载的源码:

1、脚本更新。

  a、通过bundle文件更新

  •   bundle文件

   bundle文件包含了当前所有脚本中的信息,一开始建项目的时候,在asset中会有一个index.android.bundle文件。之后

  每次更新的时候,我们需要通过以下命令生成bundle文件。命令中的bundle文件夹可以指定到任何地方。

  •       加载bundle文件

将生成的bundle文件放到服务器上。app每次启动的时候调用MainActivity,该Activity需要改成普通的Activity,而不是

ReactActivity。

为什么我们不直接替换asset下的bundle文件。因为我们没有权限修改asset文件夹。

MainActivity只做一件事,比较版本,决定是否下载新的bundle压缩文件,并且解压。最后跳转到react主页的

ReactActivity。另外,为了防止后退到MainActivity为空白,需要在跳转的时候调用finish()方法。

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        //startActivity(new Intent(this,RNActivity.class));
        // 下载更新包
        load();
    }
 /**
     * 下载更新包
     */
    private void load() {
        checkVersion();
    }

    /**
     * 检查版本号
     */
    private void checkVersion() {
        // 版本获取待实现

        // 如果不需要下载
        //startActivity(new Intent(this,RNActivity.class));

        // 如果需要下载
        String url = "http://192.168.0.121/mshop/bundle/1.0.0.zip";
        downLoadBundle(url);
    }


/**
     * 下载最新Bundle
     */
    private void downLoadBundle(String url) {

        // 1.下载前检查SD卡是否存在更新包文件夹
        HotUpdateUtil.checkPackage(getApplicationContext(), FileConstant.LOCAL_FOLDER);
        // 2.下载
        DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager
                .Request(Uri.parse(url));
        //request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE| DownloadManager.Request.NETWORK_WIFI);
        request.setDestinationUri(Uri.parse("file://"+ FileConstant.JS_PATCH_LOCAL_PATH));
        mDownLoadId = downloadManager.enqueue(request);
        registeReceiver();
    }

    private void registeReceiver() {
        localReceiver = new CompleteReceiver(this);
        registerReceiver(localReceiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    private class CompleteReceiver extends BroadcastReceiver {

        private Activity activity;

        public CompleteReceiver(Activity activity){
            this.activity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
            if(completeId == mDownLoadId) {
                Log.i(TAG, "下载完成");
                HotUpdateUtil.handleZIP(getApplicationContext());
                startActivity(new Intent(context,RNActivity.class));
                this.activity.finish();
            }
        }

    }
  其中HotUpdateUtil.handleZip则是解压删除压缩文件

主页的ReactActivity主要做一件事,绑定到主页对应的js脚本。

public class RNActivity extends ReactActivity {

    @Override    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    protected String getMainComponentName() {
        return "HotUpdateProject";
    }

    @Override
    public void onBackPressed() {
        System.exit(0);
    }

}

目前为止,我们已经下载了服务器最新的bundle文件了。那么,我们怎么获取呢?接着往下走。

  •  指定Bundle文件加载路径

  react-native为我们提供了可指定bundle文件加载路径的方式,实现ReactApplication接口,实现其中的

getReactNativeHost方法,需要返回一个ReactNativeHost。在ReactNativeHost这个抽象类中,我们可以实现其中

的getJSBundleFile方法。该方法返回null,则加载asset下的bundle文件。否则加载返回值所在路径的bundle文件。

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

      //@Nullable
      @Override
      protected String getJSBundleFile() {
        File file = new File (FileConstant.JS_BUNDLE_LOCAL_PATH);
        if(file != null && file.exists()) {
            Toast.makeText(MainApplication.getApplicationontext(), "更新的bundle", Toast.LENGTH_SHORT).show();
          return FileConstant.JS_BUNDLE_LOCAL_PATH;
        } else {
          return super.getJSBundleFile();
        }
      }

      @Override
      public boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
      }

      @Override
      protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                mCommPackage
        );
      }
    };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

这样我们就可以热更新脚本了。

  b、通过补丁文件更新

   更新文件当然是越小越好,虽然我们之前把bundle压缩后传递的,但是如果能差异化更新就更好了。

这个留到下篇文章再做总结吧。

2、图片更新。

 图片更新可能遇到的问题会有点多,所以这里从图片加载源码开始分析。react-native版本号为0.52.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值