Вызов android runOnUiThread из cocos2dx может заставить элемент меню мигать

Недавно я играл с cocos2dx, и иногда мне нужно вызвать код Java, чтобы выполнить какую-то работу, специфичную для Android. Поэтому я добавляю статический метод в код Java и вызываю метод runOnUiThread для выполнения задания. И С++ вызывает статический метод Java.

Это действительно работает нормально, за исключением того, что ИНОГДА вызов заставит элемент меню, который запускает вызов, мигать, в то время как в других случаях он выглядит идеально.

У меня есть функция общего доступа, и код выглядит так, как показано ниже, кнопка общего доступа (пункт меню) иногда мигает после того, как я нажимаю на нее. Кто-нибудь может мне помочь? Спасибо!

Я помню, что где-то видел похожую проблему, но просто не мог сегодня найти ее в Google...

Джава

...
public static void onShare(final int mode, final int score) {
    ((AppActivity)mContext).runOnUiThread(new Runnable() {
    public void run() {
        Intent sendIntent = new Intent();
        sendIntent.setAction(Intent.ACTION_SEND);
        if(mode == 0) {
            sendIntent.putExtra(Intent.EXTRA_TEXT, ((AppActivity)mContext).getResources().getString(R.string.share_content0, score));
        }
        else {
            sendIntent.putExtra(Intent.EXTRA_TEXT, ((AppActivity)mContext).getResources().getString(R.string.share_content1, score));
        }
        sendIntent.setType("text/plain");
        ((AppActivity)mContext).startActivity(Intent.createChooser(sendIntent, ((AppActivity)mContext).getResources().getString(R.string.send_to)));
    }
    });
}
...

C++, платформа.cpp

...
void doShare(int mode, int score) {
    JniMethodInfo t;
    if( JniHelper::getStaticMethodInfo(t,APPACTIVITY,
        "onShare", "(II)V")) {
        t.env->CallStaticIntMethod(t.classID, t.methodID, mode, score);
    }
}
...

C++, HelloScene.cpp

...
void GameBase::onGameOver(){
...
    auto menuShare = MenuItemFont::create(sr->getString(RSTR::share), CC_CALLBACK_1(GameBase::onShare, this));
...
}
...
void GameBase::onShare(Ref* pSender){
    CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(SOUND_BTN);
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
    doShare(this->_mode, this->_best);
#endif /* CC_TARGET_PLATFORM */
}
....

* sr->getString(RSTR::share), это для поддержки нескольких языков, возвращает текст 'Share' в английской среде.

AppDelegate.cpp

void AppDelegate::applicationDidEnterBackground() {
    director->pause();
    director->stopAnimation();
    GameBase *game;
    auto scene = director->getRunningScene();
    if (game = dynamic_cast<GameBase *>(scene->getChildByTag(TAG_GAMESCENE))) {
        game->onSaveProgress();
    }
}

void AppDelegate::applicationWillEnterForeground() {
    director->resume();
    director->startAnimation(); 
}

person Qianqian    schedule 26.05.2014    source источник
comment
Что именно это мерцание вы имеете в виду? Пожалуйста, дополните.   -  person Syed Mauze Rehan    schedule 26.05.2014
comment
@ Al-mo, Мои извинения за недостаточно ясность. Под миганием я подразумеваю, что пункт меню часто меняется между выбранным статусом и нормальным статусом. Возьмем, к примеру, MenuItemFont, текст будет меняться между большим и меньшим размером.   -  person Qianqian    schedule 26.05.2014
comment
Я должен увидеть это, чтобы понять это, но мы столкнулись с аналогичной проблемой, в которой спрайты давали эффект рывков (это тоже выключается и включается, как вы упомянули), причиной оказалось переключение нашего приложения с фона на передний план без приостановка АНИМАЦИИ при этом ... может быть, это ваша проблема? Это мое предположение.   -  person Syed Mauze Rehan    schedule 26.05.2014
comment
Спасибо за комментарии! Я постараюсь сделать видео об этом. Я не уверен, что анимация, о которой вы упомянули, делала свое дело. Но я не сильно изменил файл appDelegate.cpp, и действие по умолчанию переключения между фоном/передним планом имеет код обработки анимации. Вы наблюдали эффект рывков время от времени или постоянно?   -  person Qianqian    schedule 27.05.2014
comment
В большинстве случаев (это было во время входа в Facebook, когда мы нажимали кнопку, это давало эффект рывков), следующий фрагмент кода исправлял это ››› applicationDidEnterBackground ››› CCDirector::sharedDirector()-›pause(); ======== И ======== ››› applicationWillEnterForeground ››› CCDirector::sharedDirector()-›resume();   -  person Syed Mauze Rehan    schedule 27.05.2014
comment
Благодарю вас! Я попробую это, когда вернусь домой сегодня вечером. Похоже, это может решить эту проблему, хотя в моем случае это происходит только в 3 из 10 раз.   -  person Qianqian    schedule 27.05.2014
comment
Я попробовал это, но у меня это не сработало, поэтому я все еще иногда вижу мигающий элемент. Все равно спасибо!   -  person Qianqian    schedule 27.05.2014
comment
Ну, теперь мне нужно увидеть код!   -  person Syed Mauze Rehan    schedule 28.05.2014
comment
@ Al-mo, пожалуйста, посмотрите отредактированный код, куда я только что добавил полный связанный код. Благодарю вас!   -  person Qianqian    schedule 29.05.2014
comment
Могу я увидеть AppDelegate.cpp? Потому что для меня (я не знаю, что об этом думают другие) этот фрагмент кода не вызывает этой проблемы. Это, безусловно, связано с тем, что ваша активность переходит с переднего плана на фон и обратно.   -  person Syed Mauze Rehan    schedule 29.05.2014
comment
Здравствуйте, AI-mo, спасибо за помощь, и теперь я разместил код делегата приложения. Единственная разница между автоматически сгенерированным кодом заключается в том, что я добавил паузу/возобновление, как вы предложили, и сохранение прогресса на EnterBackground.   -  person Qianqian    schedule 29.05.2014
comment
Я вижу, что вы делаете это на Android, попробуйте использовать любую из двух пар (пауза/возобновление и запуск/остановка) IMO, пауза/возобновление должно работать. Под любым из двух я имел в виду ТОЛЬКО 1 пару за раз. Я сам использовал только паузу/возобновление и эффект рывков по пунктам меню перестал происходить. Не используйте оба, как у вас. Если даже это не сработает, я либо подергаю себя за волосы, либо спрошу у вас всю кодовую базу!   -  person Syed Mauze Rehan    schedule 29.05.2014
comment
Хорошо, я приму предложенный способ. Но я не уверен, связано ли это с анимацией при входе/выходе из фона. У меня есть еще одна сцена, где другие анимации останавливаются, а иногда мигает только выбранный пункт меню. В любом случае, я попробую.   -  person Qianqian    schedule 30.05.2014
comment
где другие анимации останавливаются, в то время как только выбранный пункт меню иногда мигает ››› точно такая же проблема, с которой мы столкнулись.   -  person Syed Mauze Rehan    schedule 30.05.2014
comment
Я попытался удалить анимацию остановки/запуска и вместо этого использовал только паузу/возобновление. Удивительно, но я больше не видел проблемы! Спасибо вам за помощь! Не могли бы вы опубликовать это как отдельный ответ, и я приму его. (Я не могу принять комментарий в качестве ответа). Еще раз спасибо за помощь на всем пути ~   -  person Qianqian    schedule 30.05.2014


Ответы (2)


В вашем AppDelegate.cpp

Функция >>> applicationDidEnterBackground

А в функции >>> applicationWillEnterForeground

Я бы посоветовал вам использовать директивы С++, чтобы различать фрагменты кода для iOS и Android.

Для части Android используйте только пару PAUSE/RESUME, а для iOS используйте ту, которую вы вставили.

Так что это было бы

//applicationDidEnterBackground 
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
    director->pause();
#else
    director->pause();
    director->stopAnimation();
#endif

//applicationWillEnterForeground 
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
    director->resume();
#else
    director->resume();
    director->startAnimation(); 
#endif

Надеюсь это поможет!

person Syed Mauze Rehan    schedule 31.05.2014

Я использую следующий код в эквиваленте platform.cpp

    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    void onShare() {
         cocos2d::JniMethodInfo t;
        if (cocos2d::JniHelper::getStaticMethodInfo(t
                                                    , NativeActivityClassName
                                                    , "onShare"
                                                    , "()V"))
        {
            t.env->CallStaticVoidMethod(t.classID, t.methodID);
            t.env->DeleteLocalRef(t.classID);
        }
    }

    #endif

Он отлично работает, не мигая кнопка «Поделиться». Вы звоните по-другому?

person essess    schedule 26.05.2014
comment
не могли бы вы поделиться строкой, где вы создаете пункт меню? - person essess; 26.05.2014
comment
спасибо за ответ, вот код: auto share = MenuItemFont::create(Share, CC_CALLBACK_1(HelloWorld::onShareCallback, this)); автоматическое меню = Menu::create(share, nullptr); Как я уже сказал, большую часть времени он работает идеально, но если я внимательно смотрю на кнопку «Поделиться», иногда она просто часто переключается между большим и меньшим размером и останавливается только после закрытия диалогового окна общего доступа. На самом деле меня это не сильно беспокоит, ведь это не очень заметно, но я просто хочу знать, почему. - person Qianqian; 27.05.2014