coco2d-js在HTML上可以运行,但是打包apk后会黑屏

刚开始学习cocos2d-js,在网页上运行或者调试自己做的游戏的时候没有任何问题,但是当我把程序发布到android上测试的时候会黑屏。也就是说运行在手机上的apk只有漆黑一片。如果我们看到logcat打印的日志就会发现其实是因为出错了。出错的原因涉及到js跟cocos2d-x的内存管理机制。

js的内存管理机制是使用两种策略-------引用计数跟标记清除。

cocos2d-x用的是一种更原始的半自动化方案

想要详细了解的话可以查询一下相关的资料


下面这个例子就是在html上可以运行,但是在手机上会黑屏:

var TestLayer = cc.Layer.extend({
    ctor: function () {
        this._super();
        
        var sp = new cc.Sprite(res.test);
        this.scheduleOnce(function () {
            this.addChild(sp);
            sp.x = cc.winSize.width/2;
            sp.y = cc.winSize.height/2;
        }.bind(this),2); //两秒后再添加到舞台
    }
});

var Game = cc.Scene.extend({
    onEnter: function () {
        this._super();
        var layer = TestLayer();
        this.addChild(layer);
    }
});
看logcat的打印的日志的话有Invalid Native Objext

就是因为内存机制的不同,在手机上运行的话新建的sp精灵没有马上添加到舞台上,sp就会马上被收回。两秒后再次使用的话就会报错。


解决方案就是:运用retain 跟 release配合

用retain可以让cocos2d-x的内存机制使sp的计数器变为2,然后内存就不会把sp对象回收,如果我们也不想让sp精灵一直存在的话在适当的地方要记得release方法

上面的例子这样改就不会出错了:

var TestLayer = cc.Layer.extend({
    ctor: function () {
        this._super();

        var sp = new cc.Sprite(res.test);
        sp.retain();    //计数器加一
        this.scheduleOnce(function () {
            this.addChild(sp);
            this.release();   //计数器减一
            sp.x = cc.winSize.width/2;
            sp.y = cc.winSize.height/2;
        }.bind(this),2); //两秒后再添加到舞台
    }
});

var Game = cc.Scene.extend({
    onEnter: function () {
        this._super();
        var layer = TestLayer();
        this.addChild(layer);
    }
});

一般我们需要在以下两中情况下注意内存管理:

1,新建的节点不马上添加到舞台中

2,舞台删除了这个节点,但是下一帧还要使用这个节点

因为节点在脱离了显示列表后就会被内存机制马上回收。需要用retain保存下来。在合适的地方release,不然该节点会永远存在。

展开阅读全文

没有更多推荐了,返回首页