diff --git a/Examples/CodePushDemoAppNewArch/android/app/src/main/java/com/codepushdemoappnewarch/MainApplication.kt b/Examples/CodePushDemoAppNewArch/android/app/src/main/java/com/codepushdemoappnewarch/MainApplication.kt index 01ecef30e..1c37a834e 100644 --- a/Examples/CodePushDemoAppNewArch/android/app/src/main/java/com/codepushdemoappnewarch/MainApplication.kt +++ b/Examples/CodePushDemoAppNewArch/android/app/src/main/java/com/codepushdemoappnewarch/MainApplication.kt @@ -17,16 +17,12 @@ import com.microsoft.codepush.react.CodePush @OptIn(UnstableReactNativeAPI::class) class MainApplication : Application(), ReactApplication { - val defaultPackageList by lazy { - PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: - // add(MyReactNativePackage()) - } - } - override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) { - override fun getPackages(): List = defaultPackageList + override fun getPackages(): List = PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + } override fun getJSMainModuleName(): String = "index" diff --git a/README.md b/README.md index 95b36f1d6..62dfa3bfe 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d * For class component ```javascript - import codePush from "react-native-code-push"; + import codePush from "@code-push-next/react-native-code-push"; class MyApp extends Component { } @@ -130,7 +130,7 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d * For functional component ```javascript - import codePush from "react-native-code-push"; + import codePush from "@code-push-next/react-native-code-push"; let MyApp: () => React$Node = () => { } @@ -145,7 +145,7 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d * For class component ```javascript - import codePush from "react-native-code-push"; + import codePush from "@code-push-next/react-native-code-push"; @codePush class MyApp extends Component { @@ -155,7 +155,7 @@ The simplest way to do this is to "CodePush-ify" your app's root component. To d * For functional component ```javascript - import codePush from "react-native-code-push"; + import codePush from "@code-push-next/react-native-code-push"; const MyApp: () => React$Node = () => { } diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index 17f5a5bd8..606237772 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -21,6 +21,18 @@ import java.util.List; public class CodePush implements ReactPackage { + private static final Object LOCK = new Object(); + private static volatile CodePush mCurrentInstance; + public static CodePush getInstance(String deploymentKey, Context context, boolean isDebugMode) { + if (mCurrentInstance == null) { + synchronized (LOCK) { + if (mCurrentInstance == null) { + mCurrentInstance = new CodePush(deploymentKey, context, isDebugMode); + } + } + } + return mCurrentInstance; + } private static boolean sIsRunningBinaryVersion = false; private static boolean sNeedToReportRollback = false; @@ -49,8 +61,6 @@ public class CodePush implements ReactPackage { private static ReactHostHolder mReactHostHolder; - private static CodePush mCurrentInstance; - public CodePush(String deploymentKey, Context context) { this(deploymentKey, context, false); } @@ -59,7 +69,7 @@ public static String getServiceUrl() { return mServerUrl; } - public CodePush(String deploymentKey, Context context, boolean isDebugMode) { + private CodePush(String deploymentKey, Context context, boolean isDebugMode) { mContext = context.getApplicationContext(); mUpdateManager = new CodePushUpdateManager(context.getFilesDir().getAbsolutePath()); @@ -90,18 +100,18 @@ public CodePush(String deploymentKey, Context context, boolean isDebugMode) { initializeUpdateAfterRestart(); } - public CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl) { + private CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl) { this(deploymentKey, context, isDebugMode); mServerUrl = serverUrl; } - public CodePush(String deploymentKey, Context context, boolean isDebugMode, int publicKeyResourceDescriptor) { + private CodePush(String deploymentKey, Context context, boolean isDebugMode, int publicKeyResourceDescriptor) { this(deploymentKey, context, isDebugMode); mPublicKey = getPublicKeyByResourceDescriptor(publicKeyResourceDescriptor); } - public CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl, Integer publicKeyResourceDescriptor) { + private CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl, Integer publicKeyResourceDescriptor) { this(deploymentKey, context, isDebugMode); if (publicKeyResourceDescriptor != null) { diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushBuilder.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushBuilder.java deleted file mode 100644 index ee1eb4a3b..000000000 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.microsoft.codepush.react; - -import android.content.Context; - -public class CodePushBuilder { - private String mDeploymentKey; - private Context mContext; - - private boolean mIsDebugMode; - private String mServerUrl; - private Integer mPublicKeyResourceDescriptor; - - public CodePushBuilder(String deploymentKey, Context context) { - this.mDeploymentKey = deploymentKey; - this.mContext = context; - this.mServerUrl = CodePush.getServiceUrl(); - } - - public CodePushBuilder setIsDebugMode(boolean isDebugMode) { - this.mIsDebugMode = isDebugMode; - return this; - } - - public CodePushBuilder setServerUrl(String serverUrl) { - this.mServerUrl = serverUrl; - return this; - } - - public CodePushBuilder setPublicKeyResourceDescriptor(int publicKeyResourceDescriptor) { - this.mPublicKeyResourceDescriptor = publicKeyResourceDescriptor; - return this; - } - - public CodePush build() { - return new CodePush(this.mDeploymentKey, this.mContext, this.mIsDebugMode, this.mServerUrl, this.mPublicKeyResourceDescriptor); - } -} diff --git a/code-push-plugin-testing-framework/script/testConfig.js b/code-push-plugin-testing-framework/script/testConfig.js index 7b351695a..17a80cf1d 100644 --- a/code-push-plugin-testing-framework/script/testConfig.js +++ b/code-push-plugin-testing-framework/script/testConfig.js @@ -12,7 +12,7 @@ var DEFAULT_UPDATES_DIRECTORY = path.join(os.tmpdir(), TestUtil_1.TestUtil.getPl var DEFAULT_PLUGIN_PATH = path.join(__dirname, "../.."); var NPM_PLUGIN_PATH = TestUtil_1.TestUtil.getPluginName(); var SETUP_FLAG_NAME = "--setup"; -var DEFAULT_PLUGIN_TGZ_NAME = TestUtil_1.TestUtil.getPluginName() + "-" + TestUtil_1.TestUtil.getPluginVersion() + ".tgz"; +var DEFAULT_PLUGIN_TGZ_NAME = TestUtil_1.TestUtil.getPluginName().replace("@", "").replace("/", "-") + "-" + TestUtil_1.TestUtil.getPluginVersion() + ".tgz"; // CONST VARIABLES exports.TestAppName = "TestCodePush"; exports.TestNamespace = "com.testcodepush"; diff --git a/docs/api-android.md b/docs/api-android.md index 0d5307edc..092bfbb4a 100644 --- a/docs/api-android.md +++ b/docs/api-android.md @@ -1,18 +1,19 @@ -### Resource Configuration +### Resource Configuration Since `autolinking` uses `react-native.config.js` to link plugins, constructors are specified in that file. But you can override custom variables to manage the CodePush plugin by placing these values in string resources. -* __Public Key__ - used for bundle verification in the Code Signing Feature. Please refer to [Code Signing](setup-android.md#code-signing-setup) section for more details about the Code Signing Feature. - To set the public key, you should add the content of the public key to `strings.xml` with name `CodePushPublicKey`. CodePush automatically gets this property and enables the Code Signing feature. For example: - ```xml - your-public-key - ``` +- **Public Key** - used for bundle verification in the Code Signing Feature. Please refer to [Code Signing](setup-android.md#code-signing-setup) section for more details about the Code Signing Feature. + To set the public key, you should add the content of the public key to `strings.xml` with name `CodePushPublicKey`. CodePush automatically gets this property and enables the Code Signing feature. For example: -* __Server Url__ - used for specifying CodePush Server Url. - The Default value: "https://codepush.appcenter.ms/" is overridden by adding your path to `strings.xml` with name `CodePushServerUrl`. CodePush automatically gets this property and will use this path to send requests. For example: - ```xml - https://yourcodepush.server.com - ``` + ```xml + your-public-key + ``` + +- **Server Url** - used for specifying CodePush Server Url. + The Default value: "https://codepush.appcenter.ms/" is overridden by adding your path to `strings.xml` with name `CodePushServerUrl`. CodePush automatically gets this property and will use this path to send requests. For example: + ```xml + https://yourcodepush.server.com + ``` The Java API is made available by importing the `com.microsoft.codepush.react.CodePush` class into your `MainActivity.java` file, and consists of a single public class named `CodePush`. @@ -24,58 +25,28 @@ Constructs the CodePush client runtime and represents the `ReactPackage` instanc ##### Constructors -- __CodePush(String deploymentKey, Activity mainActivity)__ - Creates a new instance of the CodePush runtime, that will be used to query the service for updates via the provided deployment key. The `mainActivity` parameter should always be set to `this` when configuring your React packages list inside the `MainActivity` class. This constructor puts the CodePush runtime into "release mode", so if you want to enable debugging behavior, use the following constructor instead. - -- __CodePush(String deploymentKey, Activity mainActivity, bool isDebugMode)__ - Equivalent to the previous constructor but allows you to specify whether you want the CodePush runtime to be in debug mode or not. When using this constructor, the `isDebugMode` parameter should always be set to `BuildConfig.DEBUG` in order to stay synchronized with your build type. When putting CodePush into debug mode, the following behaviors are enabled: - - 1. Old CodePush updates aren't deleted from storage whenever a new binary is deployed to the emulator/device. This behavior enables you to deploy new binaries, without bumping the version during development, and without continuously getting the same update every time your app calls `sync`. - - 2. The local cache that the React Native runtime maintains in debug mode is deleted whenever a CodePush update is installed. This ensures that when the app is restarted after an update is applied, you will see the expected changes. As soon as [this PR](https://github.com/facebook/react-native/pull/4738) is merged, we won't need to do this anymore. - -- __CodePush(String deploymentKey, Context context, boolean isDebugMode, Integer publicKeyResourceDescriptor)__ - Equivalent to the previous constructor, but allows you to specify the public key resource descriptor needed to read public key content. Please refer to [Code Signing](setup-android.md#code-signing-setup) section for more details about the Code Signing Feature. - -- __CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl)__ Constructor allows you to specify CodePush Server Url. The Default value: `"https://codepush.appcenter.ms/"` is overridden by value specified in `serverUrl`. - -##### Builder - -As an alternative to constructors *you can also use `CodePushBuilder`* to setup a CodePush instance configured with *only parameters you want*. - -```java - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage(), - new CodePushBuilder("deployment-key-here",getApplicationContext()) - .setIsDebugMode(BuildConfig.DEBUG) - .setPublicKeyResourceDescriptor(R.string.publicKey) - .setServerUrl("https://yourcodepush.server.com") - .build() //return configured CodePush instance - ); - } -``` - -`CodePushBuilder` methods: +- **CodePush(String deploymentKey, Activity mainActivity)** - Creates a new instance of the CodePush runtime, that will be used to query the service for updates via the provided deployment key. The `mainActivity` parameter should always be set to `this` when configuring your React packages list inside the `MainActivity` class. This constructor puts the CodePush runtime into "release mode", so if you want to enable debugging behavior, use the following constructor instead. -* __public CodePushBuilder(String deploymentKey, Context context)__ - setup same parameters as via __CodePush(String deploymentKey, Activity mainActivity)__ +- **CodePush(String deploymentKey, Activity mainActivity, bool isDebugMode)** - Equivalent to the previous constructor but allows you to specify whether you want the CodePush runtime to be in debug mode or not. When using this constructor, the `isDebugMode` parameter should always be set to `BuildConfig.DEBUG` in order to stay synchronized with your build type. When putting CodePush into debug mode, the following behaviors are enabled: -* __public CodePushBuilder setIsDebugMode(boolean isDebugMode)__ - allows you to specify whether you want the CodePush runtime to be in debug mode or not. Default value: `false`. + 1. Old CodePush updates aren't deleted from storage whenever a new binary is deployed to the emulator/device. This behavior enables you to deploy new binaries, without bumping the version during development, and without continuously getting the same update every time your app calls `sync`. -* __public CodePushBuilder setServerUrl(String serverUrl)__ - allows you to specify CodePush Server Url. Default value: `"https://codepush.appcenter.ms/"`. + 2. The local cache that the React Native runtime maintains in debug mode is deleted whenever a CodePush update is installed. This ensures that when the app is restarted after an update is applied, you will see the expected changes. As soon as [this PR](https://github.com/facebook/react-native/pull/4738) is merged, we won't need to do this anymore. -* __public CodePushBuilder setPublicKeyResourceDescriptor(int publicKeyResourceDescriptor)__ - allows you to specify Public Key resource descriptor which will be used for reading Public Key content for `strings.xml` file. Please refer to [Code Signing](setup-android.md#code-signing-setup) section for more detailed information about purpose of this parameter. +- **CodePush(String deploymentKey, Context context, boolean isDebugMode, Integer publicKeyResourceDescriptor)** - Equivalent to the previous constructor, but allows you to specify the public key resource descriptor needed to read public key content. Please refer to [Code Signing](setup-android.md#code-signing-setup) section for more details about the Code Signing Feature. -* __public CodePush build()__ - return configured `CodePush` instance. +- **CodePush(String deploymentKey, Context context, boolean isDebugMode, String serverUrl)** Constructor allows you to specify CodePush Server Url. The Default value: `"https://codepush.appcenter.ms/"` is overridden by value specified in `serverUrl`. ##### Public Methods -- __setDeploymentKey(String deploymentKey)__ - Sets the deployment key that the app should use when querying for updates. This is a dynamic alternative to setting the deployment key in Codepush constructor/builder and/or specifying a deployment key in JS when calling `checkForUpdate` or `sync`. +- **setDeploymentKey(String deploymentKey)** - Sets the deployment key that the app should use when querying for updates. This is a dynamic alternative to setting the deployment key in Codepush constructor/builder and/or specifying a deployment key in JS when calling `checkForUpdate` or `sync`. ##### Static Methods -- __getBundleUrl()__ - Returns the path to the most recent version of your app's JS bundle file, assuming that the resource name is `index.android.bundle`. If your app is using a different bundle name, then use the overloaded version of this method which allows specifying it. This method has the same resolution behavior as the Objective-C equivalent described above. +- **getBundleUrl()** - Returns the path to the most recent version of your app's JS bundle file, assuming that the resource name is `index.android.bundle`. If your app is using a different bundle name, then use the overloaded version of this method which allows specifying it. This method has the same resolution behavior as the Objective-C equivalent described above. -- __getBundleUrl(String bundleName)__ - Returns the path to the most recent version of your app's JS bundle file, using the specified resource name (like `index.android.bundle`). This method has the same resolution behavior as the Objective-C equivalent described above. +- **getBundleUrl(String bundleName)** - Returns the path to the most recent version of your app's JS bundle file, using the specified resource name (like `index.android.bundle`). This method has the same resolution behavior as the Objective-C equivalent described above. -- __getPackageFolder()__ - Returns the path to the current update folder. +- **getPackageFolder()** - Returns the path to the current update folder. -- __overrideAppVersion(String appVersionOverride)__ - Sets the version of the application's binary interface, which would otherwise default to the Play Store version specified as the `versionName` in the `build.gradle`. This should be called a single time, before the CodePush instance is constructed. +- **overrideAppVersion(String appVersionOverride)** - Sets the version of the application's binary interface, which would otherwise default to the Play Store version specified as the `versionName` in the `build.gradle`. This should be called a single time, before the CodePush instance is constructed. diff --git a/docs/setup-android.md b/docs/setup-android.md index 232c60aa2..380b2b886 100644 --- a/docs/setup-android.md +++ b/docs/setup-android.md @@ -28,25 +28,19 @@ In order to integrate CodePush into your Android project, please perform the fol import com.microsoft.codepush.react.CodePush class MainApplication : Application(), ReactApplication { - - // PackageList must be instantiated only one in application lifetime. - val defaultPackageList by lazy { - PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: - // add(MyReactNativePackage()) - } - } - - override val reactNativeHost: ReactNativeHost = - object : DefaultReactNativeHost(this) { - ... - - // 2. Override the getJSBundleFile method in order to let - // the CodePush runtime determine where to get the JS - // bundle location from on each app start - override fun getJSBundleFile(): String { - return CodePush.getJSBundleFile() - } + override val reactNativeHost: ReactNativeHost = + object : DefaultReactNativeHost(this) { + override fun getPackages(): List = PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + } + + // 2. Override the getJSBundleFile method in order to let + // the CodePush runtime determine where to get the JS + // bundle location from on each app start + override fun getJSBundleFile(): String { + return CodePush.getJSBundleFile() + } }; } ``` diff --git a/react-native.config.js b/react-native.config.js index 17bfb5ddc..386fbf066 100644 --- a/react-native.config.js +++ b/react-native.config.js @@ -3,7 +3,7 @@ module.exports = { platforms: { android: { packageInstance: - "new CodePush(getResources().getString(R.string.CodePushDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)", + "CodePush.getInstance(getResources().getString(R.string.CodePushDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)", sourceDir: './android/app', } } diff --git a/test/template/android/app/src/main/java/com/testcodepush/MainApplication.kt b/test/template/android/app/src/main/java/com/testcodepush/MainApplication.kt index 6fed2dd38..053e256ff 100644 --- a/test/template/android/app/src/main/java/com/testcodepush/MainApplication.kt +++ b/test/template/android/app/src/main/java/com/testcodepush/MainApplication.kt @@ -17,16 +17,14 @@ import com.microsoft.codepush.react.CodePush @OptIn(UnstableReactNativeAPI::class) class MainApplication : Application(), ReactApplication { - val defaultPackageList by lazy { - PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: - // add(MyReactNativePackage()) - } - } - override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) { - override fun getPackages(): List = defaultPackageList + override fun getPackages(): List { + val packages = PackageList(this).packages + // Packages that cannot be autolinked yet can be added manually here, for example: + // packages.add(new MyReactNativePackage()); + return packages + } override fun getJSMainModuleName(): String = "index" override fun getJSBundleFile(): String = CodePush.getJSBundleFile()