microsoft / react-native-code-push

React Native module for CodePush
http://appcenter.ms
Other
8.99k stars 1.47k forks source link

The Example for android can download bundle,but not applay #153

Closed virtoolswebplayer closed 8 years ago

virtoolswebplayer commented 8 years ago

i test the example on ios and android , ios is ok, but in android ,it failed, download bundle is ok but not applay new update when reboot

lostintangent commented 8 years ago

Are you running the app in debug mode (e.g. you ran react-native run-android)? On Android, React Native forces the JS bundle to be loaded from the packager, and therefore, doesn't consult the CodePush plugin where to get it from. So even after you install an update via CodePush, after the restart, it will still load the bundle from the packager and not from CodePush. We can't work around this unfortunately. This is usually OK during debugging since the changes that you released to CodePush were also likely made locally, so the packager would pick them up.

However, in debug mode, React Native also caches the JS bundle, and therefore, even after you restart the app, it will re-use the locally available file unless you "force" it to reload. This makes it seem like the update wasn't installed while debugging. Once again, CodePush is completely out of control of this behavior by default.

Could you try opening the dev menu and explicitly reload the bundle after you do an update? If that works, you can "automate" this by enabling "dev mode" for the CodePush plugin, which will automatically clear the JS bundle cache for you. To do this, simply pass the BuildConfig.DEBUG property as the third parameter to the CodePush class's constructor in your MainActivity.java class.

You can find more details about this constructor in the docs for the Java API. Let me know how this goes and if you have any feedback on this behavior and/or the docs. Thanks!

virtoolswebplayer commented 8 years ago

check my code

test react-native 0.17.0 + react-native-code-push 1.5.3-beta on android

download is ok -> auto restart -> alert me 'codepushDemo has stopped', -> manually restart the app -> app is up to date , but not apply update

mybundle.sh

#!/usr/bin/env bash

rm -rf ./release/*

react-native bundle --platform android  \
--entry-file index.android.js  \
--bundle-output ./release/index.android.bundle  \
--dev false

code-push release testandroid  ./release 1.0.0

MainActivity.java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReactRootView = new ReactRootView(this);

        codePush = new CodePush("this my key ", this, BuildConfig.DEBUG);

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setJSBundleFile(codePush.getBundleUrl("index.android.bundle"))
                .addPackage(codePush.getReactPackage())

                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())

                //.setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        mReactRootView.startReactApplication(mReactInstanceManager, "codepush", null);

        setContentView(mReactRootView);
    }

crossplatformdemo.js

'use strict';

import React, {
  AppRegistry,
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";

import Button from "react-native-button";
import CodePush from "react-native-code-push";

let CodePushDemoApp = React.createClass({
  async sync() {
    let self = this;
    try {
      return await CodePush.sync(
        { 
          updateDialog: true,
          installMode: CodePush.InstallMode.IMMEDIATE
        }, 
        (syncStatus) => {
          switch(syncStatus) {
            case CodePush.SyncStatus.CHECKING_FOR_UPDATE: 
              self.setState({
                syncMessage: "Checking for update."
              });
              break;
            case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
              self.setState({
                syncMessage: "Downloading package."
              });
              break;
            case CodePush.SyncStatus.AWAITING_USER_ACTION:
              self.setState({
                syncMessage: "Awaiting user action."
              });
              break;
            case CodePush.SyncStatus.INSTALLING_UPDATE:
              self.setState({
                syncMessage: "Installing update."
              });
              break;
            case CodePush.SyncStatus.UP_TO_DATE:
              self.setState({
                syncMessage: "App up to date.",
                progress: false
              });
              break;
            case CodePush.SyncStatus.UPDATE_IGNORED:
              self.setState({
                syncMessage: "Update cancelled by user.",
                progress: false
              });
              break;
            case CodePush.SyncStatus.UPDATE_INSTALLED:
              self.setState({
                syncMessage: "Update installed and will be run when the app next resumes.",
                progress: false
              });
              break;
            case CodePush.SyncStatus.UNKNOWN_ERROR:
              self.setState({
                syncMessage: "An unknown error occurred.",
                progress: false
              });
              break;
          }
        },
        (progress) => {
          self.setState({
            progress: progress
          });
        }
      );
    } catch (error) {
      CodePush.log(error);
    }
  },

  getInitialState() {
    return { };
  },

  render() {
    let syncView, syncButton, progressView;

    if (this.state.syncMessage) {
      syncView = (
        <Text style={styles.messages}>{this.state.syncMessage}</Text>
      );
    } else {
      syncButton = ( 
        <Button style={{color: 'green'}} onPress={this.sync}>
          Start Sync!
        </Button>
      );
    }

    if (this.state.progress) {
      progressView = (
        <Text style={styles.messages}>{this.state.progress.receivedBytes} of {this.state.progress.totalBytes} bytes received</Text>
      );
    }

    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          ios and anroid version 2.7
        </Text>
        {syncButton}
        {syncView}
        {progressView}
      </View>
    );
  }
});

let styles = StyleSheet.create({
  image: {
    marginTop: 50,
    width: Dimensions.get('window').width - 100,
    height: 365 * (Dimensions.get('window').width - 100) / 651,
  },
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
    paddingTop: 50
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10
  },
  messages: {
    textAlign: 'center',
  },
});

AppRegistry.registerComponent('codepush', () => CodePushDemoApp);
lostintangent commented 8 years ago

On Android, we currently only support releasing the JS bundle file directly. Could you modify your release script to specify "code-push release testandroid ./release/index.android.bundle 1.0.0" instead of uploading the entire "release" folder? This should fix your issue, as I believe the plugin is failing when it would try to install the update, since it was expecting a JS bundle file, but was getting a zip file.

Let me know if that fixes your problem. Thanks so much for the awesome details for the repro!

virtoolswebplayer commented 8 years ago

thanks a lot ' it's ok !! please close this issues

lostintangent commented 8 years ago

Yay! Thanks for confirming and I'm glad you got it working. Let us know if you run into any other issues.

kamek-pf commented 8 years ago

Hey, sorry to bump this @lostintangent , but :

On Android, React Native forces the JS bundle to be loaded from the packager

I also ran into this, and it's quite confusing that the updates aren't applied as you'd expect when in development mode.

I spent a fair part of the day trying to understand what I did wrong. Turns out everything was set up correctly, but it took me a while to figure it out. I feel like this should be mentioned in the docs.

Other than that, very nice tool, keep up the good work !