热更新js代码中只要导react-native-update包,运行时跳转rn界面就闪退



  • 如题。以下是我的demo代码
    'use strict';

    import React, {
    Component
    } from 'react';
    import {
    AppRegistry,
    Text,
    StyleSheet,
    View,
    Platform,
    Alert,
    Linking,
    } from 'react-native';
    // import {
    // isFirstTime,
    // isRolledBack,
    // packageVersion,
    // currentVersion,
    // checkUpdate,
    // downloadUpdate,
    // switchVersion,
    // switchVersionLater,
    // markSuccess,
    // } from 'react-native-update';
    var appKey = 'zvOnN-aaPmpfgazO1bFgyPEE-qXscioi';
    class MyAwesomeApp extends Component {
    constructor(props) {
    super(props);
    // 在ES6中,如果在自定义的函数里使用了this关键字,则需要对其进行“绑定”操作,否则this的指向会变为空
    // 像下面这行代码一样,在constructor中使用bind是其中一种做法(还有一些其他做法,如使用箭头函数等)
    this.checkUpdate = this.checkUpdate.bind(this);
    this.doUpdate = this.doUpdate.bind(this);
    }
    render() {
    return (
    <View style={styles.container}>
    <Text style={styles.hello}>Hello, World</Text>
    <Text style={styles.hello} onPress={this.checkUpdate}>点击检查更新</Text>

      </View>
        )
    }
    checkUpdate = () => {
        checkUpdate(appKey).then(info => {
            if (info.expired) {
                Alert.alert('提示', '您的应用版本已更新,请前往应用商店下载新的版本', [{
                    text: '确定',
                    onPress: () => {
                        info.downloadUrl && Linking.openURL(info.downloadUrl)
                    }
                }, ]);
            } else if (info.upToDate) {
                Alert.alert('提示', '您的应用版本已是最新.');
            } else {
                Alert.alert('提示', '检查到新的版本' + info.name + ',是否下载?\n' + info.description, [{
                    text: '是',
                    onPress: () => {
                        this.doUpdate(info)
                    }
                }, {
                    text: '否',
                }, ]);
            }
        }).catch(err => {
            Alert.alert('提示', '更新失败.');
        });
    };
    doUpdate = info => {
        downloadUpdate(info).then(hash => {
            Alert.alert('提示', '下载完毕,是否重启应用?', [{
                text: '是',
                onPress: () => {
                    switchVersion(hash);
                }
            }, {
                text: '否',
            }, {
                text: '下次启动时',
                onPress: () => {
                    switchVersionLater(hash);
                }
            }, ]);
        }).catch(err => {
            Alert.alert('提示', '更新失败.');
        });
    };
    

    }
    var styles = StyleSheet.create({
    container: {
    flex: 1,
    justifyContent: 'center',
    },
    hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    },
    });

    AppRegistry.registerComponent('MyProject', () => MyAwesomeApp);
    注释掉就可以正常显示,请问这是什么原因额?



  • @lxc8601 哦对了
    android studio log中会打这个错误:

    ReactNativeJS: undefined is not an object (evaluating 'd.downloadRootDir')
    是不是包有问题?


  • administrators

    没有运行rnpm link,或者rnpm link由于某种原因没有成功



  • @sunnylqm
    是这样的之前我运行rnpm link 显示是successful,但是我在java代码中导入updateContext时导不进包,我就手动import了那个module,java中倒是可以了,但是现在又出现这样的问题。我的版本是
    "react": "^15.2.1",
    "react-native": "^0.29.2",
    "react-native-update": "^2.0.1"
    之前查看帖子说rn0.29.0版本有这个bug,为何0.29.2也有这问题呢?


  • administrators



  • 我又换了rn0.28的版本,rnmp link没有反应,之前还会提示successful,如图:
    0_1470120257487_QQ截图20160802144358.png

    然后我又手动导了包,依旧会报以前那个错误:

    08-02 14:39:21.544 10618-10775/com.aoliday.android.phone E/ReactNativeJS: undefined is not an object (evaluating 'd.downloadRootDir')
    08-02 14:39:21.554 10618-10776/com.aoliday.android.phone E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
    Process: com.aoliday.android.phone, PID: 10618
    com.facebook.react.modules.core.JavascriptException: undefined is not an object (evaluating 'd.downloadRootDir'), stack:

    为啥只有我遇到这种问题啊··好蛋疼。。搞了一个星期环境还没弄好。以下是我详细java代码,拜托也有这个问题的朋友帮看看。。

    import com.facebook.react.LifecycleState;
    import com.facebook.react.ReactActivity;
    import com.facebook.react.ReactInstanceManager;
    import com.facebook.react.ReactPackage;
    import com.facebook.react.ReactRootView;
    import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
    import com.facebook.react.shell.MainReactPackage;

    import java.util.ArrayList;
    import java.util.List;

    import cn.reactnative.modules.update.UpdateContext;

    public class MyReactActivity extends ReactActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;
    @Override
    protected String getJSBundleFile() {
    return UpdateContext.getBundleUrl(this);
    }
    @Override
    protected String getMainComponentName() {
    return "MyProject";
    }

    @Override
    protected boolean getUseDeveloperSupport() {
        return false;
    }
    
    @Override
    protected List<ReactPackage> getPackages() {
        List l=new ArrayList<>();
        l.add(new MainReactPackage());
        return l;
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(false)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "MyProject", null);
        setContentView(mReactRootView);
    }
    
    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause();
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy();
        }
    }
    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
    

    }



  • 自己回复下,尝试了各种版本的RN和Rnpm貌似都报这个错误,我感觉应该和原生引入rn有一定关系,这是我唯一没有尝试的变量了。
    后来无奈之下硬着头皮看微软的code-push(英语渣),没想到还挺顺利的实现了热更新,如果有跟我问题一样的朋友不妨试一试。


登录后回复