美文网首页
react native获取app的打包/编译/构建时间

react native获取app的打包/编译/构建时间

作者: 用户77 | 来源:发表于2021-12-06 08:40 被阅读0次

    前言

    获取App的打包(构建/编译)时间,这种业务场景还是很多的,根据App的打包时间和本地/网络资源做比较,进行后续差异化操作。

    我这里大概分为两种方法,一种是在app编译构建时写入一个时间常量;另一个是能直接获取到当前文件(类)的编译时间。以此视为app的打包时间。

    具体实现是,安卓端采用第一种方法,iOS端采用第二种方法,整体代码比较简单快速有效。

    正文

    Android端:

    在Android端的module级配置文件build.gradle中,提供了defaultConfig属性配置,里面默认定义了applicationId、minSdkVersion、targetSdkVersion等配置信息。这个defaultConfig也给开发者提供了buildConfigField(type, name, value)方法,可以在构建前定义常量或者变量,构建时会生成BuildConfig.java类,编译后供给程序代码运行时调用。

    build.config文件:

    下面是build.config部分关键代码,这里定义了一个方法getCurrentTimeMillisUTC,它会在打包构建时运行,获取UTC时间如2021-11-29T05:41:50.113Z,然后赋值给名为PACKAGE_TIME的字符串(String对象),定义在构建生成的BuildConfig.java中。

    ...省略代码...
    
    static def getCurrentTimeMillisUTC() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss.SSS")
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"))
        String utcTime = sdf.format(new Date())
        return utcTime + 'Z'
    }
    
    android {
        compileSdkVersion safeExtGet('compileSdkVersion', 30)
        buildToolsVersion safeExtGet('buildToolsVersion', '30.0.2')
    
        defaultConfig {
            minSdkVersion safeExtGet('minSdkVersion', 21)
            targetSdkVersion safeExtGet('targetSdkVersion', 30)
            buildConfigField ("String", "PACKAGE_TIME", "\"" + getCurrentTimeMillisUTC() + "\"")
        }
    }
    
    ...省略代码...
    

    自动生成的BuildConfig.java文件, 文件位置在android/build/generated/source/buildConfig/debug/com/reactnative/packagetime/BuildConfig.java

    下面代码中的PACKAGE_TIME就是我们想要的app打包时间。

    /**
     * Automatically generated file. DO NOT MODIFY
     */
    package com.reactnative.packagetime;
    
    public final class BuildConfig {
      public static final boolean DEBUG = Boolean.parseBoolean("true");
      public static final String LIBRARY_PACKAGE_NAME = "com.reactnative.packagetime";
      public static final String BUILD_TYPE = "debug";
      // Field from default config.
      public static final String PACKAGE_TIME = "2021-11-29T05:41:50.113Z";
    }
    

    原生代码取值并与js通信:

    定义原生package模块

    package com.reactnative.packagetime;
    
    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.ViewManager;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class RNPackageTimePackage implements ReactPackage {
    
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new RNPackageTimeModule(reactContext));
            return modules;
        }
    
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    
    }
    

    定义原生module模块:

    package com.reactnative.packagetime;
    
    import com.facebook.react.bridge.Callback;
    import com.facebook.react.bridge.Promise;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactMethod;
    
    public class RNPackageTimeModule extends ReactContextBaseJavaModule  {
        private ReactApplicationContext mContext;
    
        public RNPackageTimeModule(ReactApplicationContext reactContext) {
            super(reactContext);
            mContext = reactContext;
        }
    
        @Override
        public String getName() {
            return "RNPackageTimeModule";
        }
    
        @ReactMethod
        public void getPackageTime(Callback callback) {
            // 通过callback异步方法和js层通信,传值
            callback.invoke(BuildConfig.PACKAGE_TIME);
        }
    
    }
    

    手动链接原生模块:

    ...省略的代码...
    
    public class MainApplication extends Application implements ReactApplication {
    
        private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
            @Override
            public boolean getUseDeveloperSupport() {
                return BuildConfig.DEBUG;
            }
    
            @Override
            protected List<ReactPackage> getPackages() {
                return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    new RNPackageTimePackage()
                );
            }
    
            @Override
            protected String getJSMainModuleName() {
                return "index";
            }
        };
    
        @Override
        public ReactNativeHost getReactNativeHost() {
            return mReactNativeHost;
        }
    }
    ...省略的代码...
    

    js调用

    import { NativeModules } from 'react-native';
    
    NativeModules.RNPackageTimeModule.getPackageTime((time: string) => {
        console.log(result); // 2021-12-05T21:51:27Z UTC时间
        console.log(new Date(result).getTime()); // 1638712287300 Unix时间戳(UTC)
    });
    

    iOS端:

    iOS端也可以利用类似Android的方法写入一个时间变量,这里就不采用了,我没有实际验证过。

    本篇文章中,iOS采用的方法是读取object-c文件的宏__DATE____TIME__,也就是当前文件的编译日期和时间。这俩个宏是ANSI C规定的6个标准宏之二,object-c作为c语言的超集,可以获取到到两个宏的值,我们可以视其为app的打包时间。

    定义原生模块RNPackageTimeModule.m代码:

    博主不太了解oc代码,所以代码逻辑写的可能不够简单,下述代码实现的是将__DATE____TIME__先格式化成UTC时间字符串,再格式化成我们想要的UTC时间格式yyyy-MM-dd\'T\'HH:mm:ss.SSS,这里的字符T保留,是做日期和时间之间的间隔标识的。

    #import <React/RCTBridgeModule.h>
    
    @interface RCT_EXTERN_MODULE(RNPackageTimeModule, NSObject)
    
    #pragma mark - get package time
    - (NSDictionary *)constantsToExport
    {
      NSString *buildDate = [NSString stringWithFormat:@"%s %s",__DATE__, __TIME__];
    
      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
      // input date format
      [dateFormatter setDateFormat:@"MMM dd yyyy HH:mm:ss"];
    
      NSDate *dateFormatted = [dateFormatter dateFromString:buildDate];
      NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
      [dateFormatter setTimeZone:timeZone];
    
      // output date format
      [dateFormatter setDateFormat:@"yyyy-MM-dd\'T\'HH:mm:ss.SSS"];
      NSString *dateString = [dateFormatter stringFromDate:dateFormatted];
    
      NSString *packageTime = [dateString stringByAppendingString:@"Z"];
        
      return @{ @"packageTime": packageTime }; // 2021-12-05T21:51:27Z
    }
    @end
    

    js代码获取,这里可以同步获取

    import { NativeModules } from 'react-native';
    
    const time = NativeModules.RNPackageTimeModule.packageTime;
    
    console.log(time); // 2021-12-05T21:51:27Z UTC时间
    console.log(new Date(time).getTime()); // 1638712287300 Unix时间戳(UTC)
    

    最后:

    我封装了一个简易的react native库,上传到了Githubnpm,大家可以学习和使用,如有任何疑问或是讨论、更好的实现方法,欢迎留言评论区。

    相关文章

      网友评论

          本文标题:react native获取app的打包/编译/构建时间

          本文链接:https://www.haomeiwen.com/subject/qtdgxrtx.html