xuexiangjys / react-native-xupdate

A React-Native plugin for XUpdate(Android Version Update Library)
Apache License 2.0
53 stars 20 forks source link

rn用的版本是0.71版本,集成了react-native-xupdate-new后打包就报失败 #39

Open jiaoxiaoyuan opened 1 year ago

jiaoxiaoyuan commented 1 year ago

rn用的版本是0.71版本,集成了react-native-xupdate-new后打包就报失败

jiaoxiaoyuan commented 1 year ago

求更, 有偿的

WangShayne commented 11 months ago

按照代码自己封装一下就可以用了

/*Native Module*/

package xx;
import android.app.Application;
import android.graphics.Color;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.xx.custom.XUpdateServiceParser;
import com.xx.http.OKHttpUpdateHttpService;
import com.xx.update.RNCustomUpdateParser;
import com.xx.update.RetryUpdateDownloader;
import com.xx.update.RetryUpdateTipDialog;
import com.xuexiang.xupdate.UpdateManager;
import com.xuexiang.xupdate.XUpdate;
import com.xuexiang.xupdate.entity.UpdateEntity;
import com.xuexiang.xupdate.entity.UpdateError;
import com.xuexiang.xupdate.listener.OnUpdateFailureListener;
import com.xuexiang.xupdate.utils.UpdateUtils;

public class UseUpdate extends ReactContextBaseJavaModule {

    public static final String KEY_ERROR_EVENT = "XUpdate_Error_Event";
    public static final String KEY_JSON_EVENT = "XUpdate_Json_Event";

    private final ReactApplicationContext mApplication;

    private RNCustomUpdateParser mCustomParser;

    public UseUpdate(ReactApplicationContext reactContext) {
        super(reactContext);
        mApplication = reactContext;
    }

    @ReactMethod
    public void addListener(String eventName) {

    }

    @ReactMethod
    public void removeListeners(Integer count) {

    }

    @NonNull
    @Override
    public String getName() {
        return "UseUpdate";
    }

    // update

    /**
     * 初始化XUpdate
     *
     * @param map
     * @param promise
     */
    @ReactMethod
    public void initXUpdate(ReadableMap map, Promise promise) {
        try {
            boolean debug = map.getBoolean("debug");
            boolean isGet = map.getBoolean("isGet");
            boolean isPostJson = map.getBoolean("isPostJson");
            int timeout = map.getInt("timeout");
            boolean isWifiOnly = map.getBoolean("isWifiOnly");
            boolean isAutoMode = map.getBoolean("isAutoMode");
            boolean supportSilentInstall = map.getBoolean("supportSilentInstall");
            boolean enableRetry = map.getBoolean("enableRetry");
            String retryContent = map.getString("retryContent");
            String retryUrl = map.getString("retryUrl");

            XUpdate.get()
                    .debug(debug)
                    //默认设置使用get请求检查版本
                    .isGet(isGet)
                    //默认设置只在wifi下检查版本更新
                    .isWifiOnly(isWifiOnly)
                    //默认设置非自动模式,可根据具体使用配置
                    .isAutoMode(isAutoMode)
                    //设置默认公共请求参数
                    .param("versionCode", UpdateUtils.getVersionCode(mApplication))
                    .param("appKey", mApplication.getPackageName())
                    //是否支持静默安装
                    .supportSilentInstall(supportSilentInstall)
                    .setOnUpdateFailureListener(new OnUpdateFailureListener() {

                        @Override
                        public void onFailure(UpdateError error) {
                            sendErrorEvent(error);
                        }
                    })

                    .setIUpdateDownLoader(new RetryUpdateDownloader(enableRetry, retryContent, retryUrl))
                    //这个必须设置!实现网络请求功能。
                    .setIUpdateHttpService(new OKHttpUpdateHttpService(timeout, isPostJson));

            ReadableMap params = map.getMap("params");
            if (params != null) {
                XUpdate.get().params(params.toHashMap());
            }
            XUpdate.get().init((Application) mApplication.getApplicationContext());

            WritableMap result = Arguments.createMap();
            result.merge(map);
            promise.resolve(result);
        } catch (Exception e) {
            e.printStackTrace();
            promise.reject(e);
        }
    }

    /**
     * 版本更新
     *
     * @param map
     */
    @ReactMethod
    public void checkUpdate(ReadableMap map, Promise promise) {

        try {
            if (!mApplication.hasCurrentActivity()) {
                promise.reject("1001", "Not attach a Activity");
            }

            String url = map.getString("url");
            boolean supportBackgroundUpdate = map.getBoolean("supportBackgroundUpdate");
            boolean isAutoMode = map.getBoolean("isAutoMode");
            boolean isCustomParse = map.getBoolean("isCustomParse");
            String themeColor = map.getString("themeColor");
            String topImageRes = map.getString("topImageRes");
            String buttonTextColor = map.getString("buttonTextColor");
            double widthRatio = map.getDouble("widthRatio");
            double heightRatio = map.getDouble("heightRatio");

            boolean overrideGlobalRetryStrategy = map.getBoolean("overrideGlobalRetryStrategy");
            boolean enableRetry = map.getBoolean("enableRetry");
            String retryContent = map.getString("retryContent");
            String retryUrl = map.getString("retryUrl");

            UpdateManager.Builder builder = XUpdate.newBuild(mApplication.getCurrentActivity())
                    .param("versionCode", UpdateUtils.getVersionCode(mApplication))
                    .param("appKey", mApplication.getPackageName())
                    .updateUrl(url)
                    .isAutoMode(isAutoMode)
                    .supportBackgroundUpdate(supportBackgroundUpdate)
                    .updateParser(new XUpdateServiceParser());

            ReadableMap params = map.getMap("params");
            if (params != null) {
                builder.params(params.toHashMap());
            }

            if (isCustomParse) {
                if (mCustomParser == null) {
                    mCustomParser = new RNCustomUpdateParser(mApplication);
                }
                builder.updateParser(mCustomParser);
            }

            updatePromptStyle(builder, themeColor, topImageRes, buttonTextColor, widthRatio, heightRatio, overrideGlobalRetryStrategy, enableRetry, retryContent, retryUrl);

            builder.update();

            promise.resolve("start updating...");

        } catch (Exception e) {
            e.printStackTrace();
            promise.reject(e);
        }
    }

    /**
     * 直接传入UpdateEntity进行版本更新
     *
     * @param map
     */
    @ReactMethod
    public void updateByUpdateEntity(ReadableMap map, Promise promise) {
        try {
            if (!mApplication.hasCurrentActivity()) {
                promise.reject("1001", "Not attach a Activity");
            }

            ReadableMap entityMap = map.getMap("updateEntity");
            UpdateEntity updateEntity = RNCustomUpdateParser.parseUpdateEntityMap(entityMap);

            boolean supportBackgroundUpdate = map.getBoolean("supportBackgroundUpdate");
            boolean isAutoMode = map.getBoolean("isAutoMode");
            String themeColor = map.getString("themeColor");
            String topImageRes = map.getString("topImageRes");
            String buttonTextColor = map.getString("buttonTextColor");
            double widthRatio = map.getDouble("widthRatio");
            double heightRatio = map.getDouble("heightRatio");

            boolean overrideGlobalRetryStrategy = map.getBoolean("overrideGlobalRetryStrategy");
            boolean enableRetry = map.getBoolean("enableRetry");
            String retryContent = map.getString("retryContent");
            String retryUrl = map.getString("retryUrl");

            UpdateManager.Builder builder = XUpdate.newBuild(mApplication.getCurrentActivity())
                    .isAutoMode(isAutoMode)
                    .supportBackgroundUpdate(supportBackgroundUpdate);

            updatePromptStyle(builder, themeColor, topImageRes, buttonTextColor, widthRatio, heightRatio, overrideGlobalRetryStrategy, enableRetry, retryContent, retryUrl);

            builder.build().update(updateEntity);

            promise.resolve("start updating...");

        } catch (Exception e) {
            e.printStackTrace();
            promise.reject(e);
        }
    }

    /**
     * 自定义解析回掉
     *
     * @param map
     */
    @ReactMethod
    public void onCustomUpdateParse(ReadableMap map) {
        if (mCustomParser != null) {
            mCustomParser.handleCustomParseResult(map);
        }
    }

    /**
     * 更新弹窗的样式
     *
     * @param builder
     * @param themeColor                  主题颜色
     * @param topImageRes                 弹窗顶部的图片
     * @param buttonTextColor             按钮文字的颜色
     * @param widthRatio                  版本更新提示器宽度占屏幕的比例
     * @param heightRatio                 版本更新提示器高度占屏幕的比例
     * @param overrideGlobalRetryStrategy
     * @param enableRetry
     * @param retryContent
     * @param retryUrl
     */
    private void updatePromptStyle(UpdateManager.Builder builder, String themeColor, String topImageRes, String buttonTextColor, double widthRatio, double heightRatio, boolean overrideGlobalRetryStrategy, boolean enableRetry, String retryContent, String retryUrl) {
        if (!TextUtils.isEmpty(themeColor)) {
            builder.promptThemeColor(Color.parseColor(themeColor));
        }
        if (!TextUtils.isEmpty(topImageRes)) {
            int topImageResId = mApplication.getCurrentActivity().getResources().getIdentifier(topImageRes, "drawable", mApplication.getCurrentActivity().getPackageName());
            builder.promptTopResId(topImageResId);
        }
        if (!TextUtils.isEmpty(buttonTextColor)) {
            builder.promptButtonTextColor(Color.parseColor(buttonTextColor));
        }
        builder.promptWidthRatio((float) widthRatio);
        builder.promptHeightRatio((float) heightRatio);
        if (overrideGlobalRetryStrategy) {
            builder.updateDownLoader(new RetryUpdateDownloader(enableRetry, retryContent, retryUrl));
        }
    }

    /**
     * 显示重试提示弹窗
     *
     * @param map
     */
    @ReactMethod
    public void showRetryUpdateTipDialog(ReadableMap map) {
        String retryContent = map.getString("retryContent");
        String retryUrl = map.getString("retryUrl");

        RetryUpdateTipDialog.show(retryContent, retryUrl);
    }

    /**
     * 发送错误信息
     *
     * @param error
     */
    private void sendErrorEvent(UpdateError error) {
        if (mApplication != null) {
            WritableMap map = Arguments.createMap();
            map.putInt("code", error.getCode());
            map.putString("message", error.getMessage());
            map.putString("detailMsg", error.getDetailMsg());
            mApplication.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit(KEY_ERROR_EVENT, map);
        }
    }

}
/* Update.js */
import {NativeEventEmitter, NativeModules, Platform} from 'react-native';

const {UseUpdate} = NativeModules;

///XUpdate初始化参数
class InitArgs {
  constructor() {
    ///是否输出日志
    this.debug = false;
    ///是否使用post请求
    this.isPost = false;
    ///post请求是否是上传json
    this.isPostJson = false;
    ///请求响应超时时间
    this.timeout = 20000;
    ///是否只在wifi下才能进行更新
    this.isWifiOnly = true;
    ///是否开启自动模式
    this.isAutoMode = false;
    ///是否支持静默安装,这个需要设备有root权限
    this.supportSilentInstall = false;
    ///在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗
    this.enableRetry = false;
    ///重试提示弹窗的提示内容
    this.retryContent = '';
    ///重试提示弹窗点击后跳转的url
    this.retryUrl = '';
    ///需要设置的公共参数
    this.params = {};
    this.versionCode = 0;
  }
}

const KEY_ERROR_EVENT = 'XUpdate_Error_Event';
const KEY_JSON_EVENT = 'XUpdate_Json_Event';

///版本更新参数
class UpdateArgs {
  constructor(url) {
    ///版本检查的地址
    this.url = url;
    ///传递的参数
    this.params = {};
    ///是否支持后台更新
    this.supportBackgroundUpdate = false;
    ///是否开启自动模式
    this.isAutoMode = false;
    ///是否是自定义解析协议
    this.isCustomParse = false;
    ///应用弹窗的主题色
    this.themeColor = '';
    ///应用弹窗的顶部图片资源名
    this.topImageRes = '';
    ///按钮文字的颜色
    this.buttonTextColor = '';
    ///版本更新提示器宽度占屏幕的比例, 不设置的话不做约束
    this.widthRatio = -1;
    ///版本更新提示器高度占屏幕的比例, 不设置的话不做约束
    this.heightRatio = -1;
    ///是否覆盖全局的重试策略
    this.overrideGlobalRetryStrategy = false;
    ///在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗
    this.enableRetry = false;
    ///重试提示弹窗的提示内容
    this.retryContent = '';
    ///重试提示弹窗点击后跳转的url
    this.retryUrl = '';
  }
}

const EventEmitter = new NativeEventEmitter(UseUpdate);

class UpdateParser {
  constructor(parser) {
    this.parseJson = parser;
  }
}

///版本更新信息
class UpdateEntity {
  //这5个值必须传
  constructor(hasUpdate, versionCode, versionName, updateContent, downloadUrl) {
    this.hasUpdate = hasUpdate;
    this.versionCode = versionCode;
    this.versionName = versionName;
    this.updateContent = updateContent;
    this.downloadUrl = downloadUrl;
  }
}

const XUpdate = {
  ///初始化
  init: (initArg = new InitArgs()) => {
    if (Platform.OS === 'ios') {
      return 'IOS端暂不支持';
    }

    return UseUpdate.initXUpdate({
      debug: initArg.debug,
      isGet: !initArg.isPost,
      isPostJson: initArg.isPostJson,
      timeout: initArg.timeout,
      isWifiOnly: initArg.isWifiOnly,
      isAutoMode: initArg.isAutoMode,
      supportSilentInstall: initArg.supportSilentInstall,
      enableRetry: initArg.enableRetry,
      retryContent: initArg.retryContent,
      retryUrl: initArg.retryUrl,
      params: initArg.params,
    });
  },

  setCustomParser: parser => {
    EventEmitter.addListener(KEY_JSON_EVENT, json => {
      if (parser !== null) {
        UseUpdate.onCustomUpdateParse(parser.parseJson(json));
      }
    });
  },

  addErrorListener: listener => {
    EventEmitter.addListener(KEY_ERROR_EVENT, listener);
  },

  removeErrorListener: listener => {
    EventEmitter.removeListener(KEY_ERROR_EVENT, listener);
  },

  ///版本更新
  update: (updateArgs = new UpdateArgs()) => {
    if (Platform.OS === 'ios') {
      return 'IOS端暂不支持';
    }

    if (
      updateArgs.url === null ||
      updateArgs.url === undefined ||
      updateArgs.url === ''
    ) {
      return 'url can not be null or empty!';
    }

    return UseUpdate.checkUpdate({
      url: updateArgs.url,
      params: updateArgs.params,
      supportBackgroundUpdate: updateArgs.supportBackgroundUpdate,
      isAutoMode: updateArgs.isAutoMode,
      isCustomParse: updateArgs.isCustomParse,
      themeColor: updateArgs.themeColor,
      topImageRes: updateArgs.topImageRes,
      buttonTextColor: updateArgs.buttonTextColor,
      widthRatio: updateArgs.widthRatio,
      heightRatio: updateArgs.heightRatio,
      overrideGlobalRetryStrategy: updateArgs.overrideGlobalRetryStrategy,
      enableRetry: updateArgs.enableRetry,
      retryContent: updateArgs.retryContent,
      retryUrl: updateArgs.retryUrl,
    });
  },

  ///直接传入UpdateEntity进行版本更新
  updateByInfo: (updateArgs = new UpdateArgs(), updateEntity) => {
    if (Platform.OS === 'ios') {
      return 'IOS端暂不支持';
    }

    return UseUpdate.updateByUpdateEntity({
      updateEntity: updateEntity,
      supportBackgroundUpdate: updateArgs.supportBackgroundUpdate,
      isAutoMode: updateArgs.isAutoMode,
      themeColor: updateArgs.themeColor,
      topImageRes: updateArgs.topImageRes,
      buttonTextColor: updateArgs.buttonTextColor,
      widthRatio: updateArgs.widthRatio,
      heightRatio: updateArgs.heightRatio,
      overrideGlobalRetryStrategy: updateArgs.overrideGlobalRetryStrategy,
      enableRetry: updateArgs.enableRetry,
      retryContent: updateArgs.retryContent,
      retryUrl: updateArgs.retryUrl,
    });
  },

  showRetryUpdateTip: (retryContent, retryUrl) => {
    if (Platform.OS === 'ios') {
      return;
    }

    UseUpdate.showRetryUpdateTipDialog({
      retryContent: retryContent,
      retryUrl: retryUrl,
    });
  },
};

export {InitArgs, UpdateArgs, UpdateEntity, UpdateParser, XUpdate};
/*Use Page*/
 useEffect(() => {
    let args = new InitArgs();
    args.debug = true;
    args.isPostJson = false;
    args.timeout = 25000;
    args.isWifiOnly = false;
    args.isAutoMode = false;
    args.supportSilentInstall = false;
    args.enableRetry = false;
    args.isPost = true;

    XUpdate.init(args)
      .then(result => {
        console.log('初始化成功:' + JSON.stringify(result));
        setUpdateMsg('初始化成功:' + JSON.stringify(result));
      })
      .catch(error => {
        setUpdateMsg('初始化失败:' + JSON.stringify(error));
      });

    //设置自定义解析
    XUpdate.setCustomParser({parseJson: customParser});
    //设置错误监听
    XUpdate.addErrorListener(errorListener);
  }, [navigation]);

  const checkUpdateDefault = () => {
    let args = new UpdateArgs(_updateUrl);
    // args.themeColor = '#FF14388E';
    // args.buttonTextColor = '#FFFFFFFF';
    XUpdate.update(args)
  };