安卓 cocos2dx 启动失败

现象

android 下在没网(无wifi,无移动网络)的情况下,启动app时,提示“很抱歉,‘XXXX’已停止运行”!

通过 eclipse 的调试,打印出信息如下:

01-03 21:40:32.095: D/VivoDaemon_SmartMultiWindowService(1769): onChange isFullScreen =1isAllowActiveSpilt = falseSmartMultWindowUtils.isSplitMode(mContext) = false
01-03 21:40:32.295: A/libc(24583): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x14 in tid 24616 (GLThread 903)

Fatal signal 11 (SIGSEGV), 说明 Native 中的代码出错了

探索与方向

原因分析

既然是有网络不出现错误,无网络时出现错误,那么和网络有关系。

既然整个程序运行有问题,那么总之是其中某一段代码引起的,那么缩小范围来定位问题。

注释网络接口

注释相关网络接口,还是跑不起来,不行!

cocos 初始化?

打log?

有同事说,“把这段初始化代码注释掉肯定可以了,然后你再一行行输出log,定位到是哪一行的问题!”

(有时候,真是说得容易,做得难呀!)当注释后,并没有想象中的解决问题


01-05 11:05:25.097: D/cocos2d-x debug info(13308): jack 0 HNLogoSceneManger::init
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack 1
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack 2
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack 2-0
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack 2-1
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack SocketHandle - 1
01-05 11:05:25.427: D/cocos2d-x debug info(13308): jack ISocketEngine::create - 1

可依然通过这中打log的蛮力的调试方式,一遍遍地缩小问题范围,“皇天不负有心人”找到是这句代码引起的:

new CSocketEngine();

创建对象失败? 甚至没有进入 CSocketEngine 这个对象中的构造函数中 (到这里,作者又陷入了深深的纠结中…)

eclipse 实时调试c++代码?

既然创建对象失败,那能不能通过 eclipse 来调试 c++ 代码呢?在线调试来获取到崩溃的位置

网上可以找到很多 eclipse 调试 c++ 代码的文章,例如:

使用eclipse调试cocos2d-x C++ 代码(编写+真机调试,放弃VS)
http://blog.csdn.net/tt5267621/article/details/8940768

按照步骤搭建,出现如下错误:

不能找到应用程序ABI

问题描述:

[2017-01-04 11:26:19 - client_test] Unknown Application ABI: 
[2017-01-04 11:26:19 - client_test] 
[2017-01-04 11:26:19 - client_test] Unable to detect application ABI's

编辑 项目文件/cocos_work/proj.android/jni/Application.mk

在文件末尾添加

APP_ABI := armeabi-v7a
APP_PLATFORM := android-15

查看当前手机指令集的方法:

D:\workspace\android-ndk-r11b\ndk-build.cmd  DUMP_APP_ABI
armeabi

下面是网上的一些讨论:

ANE 下 Android-ARM/lib/armeabi (调试模式) 或者 armeabi-v7a(发行模式)


http://bbs.csdn.net/topics/390854534

“不要用cocos2dx 3.0以上的版本。在eclipse下回坑死你。我研究了两周多,才研究透,cocos2dx-2.2.6版本如何调试C++。“


最好用2.2. 6的版本。3.0的版本模版不对
两个错一个版本不一致。修改下AndroidManifest.xml文件的参数android:minSdkVersion=”17”。
不需要增加debug,网上很多人说要增加。
自己理解:其实增加的debug是调试java的,如果要调试原生态C++完全没必要。
另外一个NDK_MODULE_PATH路径没有设好。
需要在Application.mk文件末尾增加
NDK_MODULE_PATH := E:/cocos2d-x-2.2.6;E:/cocos2d-x-2.2.6/cocos2dx/platform/third_party/android/prebuilt

还有问题参考:
cocos2d-x-2.2.6版本的README.md

命令行调试

在网上不断地搜索问题的解决方法过程中,这篇文章提到一种可行方法:

http://stackoverflow.com/questions/24334080/how-to-debug-cocos2d-x-3-native-code-on-android-device

adb logcat | $NDK_ROOT/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi

这条命令,要求在 linux 下执行,所以…

安装 cygwin

网上下载 cygwin 的安装包,并选择镜像路径:

http://mirrors.163.com/cygwin/

配置NDK

你必须重新设置NDK_MODULE_PATH到环境变量中

export NDK_MODULE_PATH=/cygdrive/d/xiaochan/workspace/cocos2d-x-3.10:/cygdrive/d/xiaochan/workspace/cocos2d-x-3.10/cocos:/cygdrive/d/xiaochan/workspace/cocos2d-x-3.10/external

/cygdrive/d/workspace/android-ndk-r11b/ndk-build.cmd  DUMP_APP_ABI

/cygdrive/d/workspace/android-ndk-r11b/ndk-gdb.cmd

/cygdrive/d/workspace/android-ndk-r11b/adb.cmd

/cygdrive/d/xiaochan/android-sdk-windows/platform-tools/

虽然安装了 cygwin,可对 android 的命令配置不熟悉,由于项目进度,不得不暂时放弃!

c++ socoket 的问题

想从类的初始化流程(父类构造函数)中来寻找答案,无果!

问题解决

“能不能在程序入口位置,获取当前网络状态,根据结构来进行相应的处理呢?”

和同事讨论得到这种方法:

    tagNetworkStatus netStatus = 获取网络状态值(根据底层android 和 ios的接口);

    // 启动时判断网络状态
    if (netStatus == Network_None)
    {
        // 创建显示按钮
        auto btnReload = cocos2d::ui::Button::create("public/Button_Close.png");
        btnReload->setPosition(cocos2d::Vec2(m_kUseSize.width / 2, m_kUseSize.height / 2));
        btnReload->setName("btn_exit_reload");
        btnReload->addTouchEventListener(CC_CALLBACK_2(HNLogoSceneManger::clickBtnReload, this));

        this->addChild(btnReload);
    }



// cocos2d 的按钮
// 记得包含: #include "ui/CocosGUI.h"; using namespace cocos2d::ui;
void HNLogoSceneManger::clickBtnReload(cocos2d::Ref* pSender, Widget::TouchEventType event)
{
    checkNetAndGo();
}

void HNLogoSceneManger::checkNetAndGo()
{
    // 获取网路状态值
    tagNetworkStatus netStatus = MissionWeiXin::Instance().checkNetWorkStatus();

    // 启动时判断网络状态
    if (netStatus != Network_None)
    {
        // 移除刷新退出按钮
        this->removeChildByName("btn_exit_reload");

        scheduleOnce(schedule_selector(HNLogoSceneManger::GoGame), 0.2f);
    }
}

如何在网络状态恢复的时候,用户如何处理呢?

小插曲,添加按钮响应即可,当点击按钮时,重新执行判断刷新请求。如上代码所示。

总结

这个问题解决过程历时一天半,其中的辛酸难熬,以及最后的释怀的喜悦,又一次是软件程序员一直尝试的!
刚开始心里还在嘀咕“这个问题有必要解决吗?怎么可能有手机没网的”,同事的思路:“当然后会出现这种情况的,肯定要解决呀!”
必须要解决时,去不断搜索,可心里一直在想着:“这怎么办呀?这怎么办呀?解决不了怎么办呀?”,陷入到这种纠结中实属没有必要。
直到最后,同事的想法,在入口位置做判断,解决了这个问题!

由此可见:

软件,是需要朋友一起讨论的!
软件,是要对自己有信心的!

后来,对于如何显示刷新网络按钮,按钮上放什么文字,依然是需要考虑的地方,这个就留给美工来发挥了,每个人有分工,事情也有轻重!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值