Help! Can't call new activity.

Hi, I’m trying to call a new activity but it’s a hit or miss kind of deal.

Sometimes the new activity gets called but most of the time the main application just closes. I get a warning message like “Activity pause timeout for HistoryRecord”.

Thanks

Could you explain it more detail? I can not catch it.

This is a bit different. I’ve posted about calling an activity, this one is about updating the UI thread. I’ve done UI update via async, handlers and threads, all of them fails. Openfeint handles the thread update so this is a very good example. You need openfeint api for this.

I’ve modified the Helloworld sample to test if this is only happening in the application we are developing. Sadly, the problem stays the same. I’m beginning to think this is a bug.

Here are the codes.

Native Side

AppDelegate.cpp

#include "AppDelegate.h"

#include "cocos2d.h"
#include "HelloWorldScene.h"

USING_NS_CC;

AppDelegate::AppDelegate()
{

}

AppDelegate::~AppDelegate()
{
}

bool AppDelegate::initInstance()
{
    bool bRet = false;
    do 
    {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

        // Initialize OpenGLView instance, that release by CCDirector when application terminate.
        // The HelloWorld is designed as HVGA.
        CCEGLView * pMainWnd = new CCEGLView();
        CC_BREAK_IF(! pMainWnd
            || ! pMainWnd->Create(TEXT("cocos2d: Hello World"), 480, 320));

#endif  // CC_PLATFORM_WIN32

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

        // OpenGLView initialized in testsAppDelegate.mm on ios platform, nothing need to do here.

#endif  // CC_PLATFORM_IOS

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

        // OpenGLView initialized in HelloWorld/android/jni/helloworld/main.cpp
        // the default setting is to create a fullscreen view
        // if you want to use auto-scale, please enable view->create(320,480) in main.cpp

#endif  // CC_PLATFORM_ANDROID

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)

        // Initialize OpenGLView instance, that release by CCDirector when application terminate.
        // The HelloWorld is designed as HVGA.
        CCEGLView* pMainWnd = new CCEGLView(this);
        CC_BREAK_IF(! pMainWnd || ! pMainWnd->Create(320,480, WM_WINDOW_ROTATE_MODE_CW));

#ifndef _TRANZDA_VM_  
        // on wophone emulator, we copy resources files to Work7/NEWPLUS/TDA_DATA/Data/ folder instead of zip file
        cocos2d::CCFileUtils::setResource("HelloWorld.zip");
#endif

#endif  // CC_PLATFORM_WOPHONE

#if (CC_TARGET_PLATFORM == CC_PLATFORM_AIRPLAY)
        // MaxAksenov said it's NOT a very elegant solution. I agree, haha
        CCDirector::sharedDirector()->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);
#endif
        bRet = true;
    } while (0);
    return bRet;
}

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());

    // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
//     pDirector->enableRetinaDisplay(true);

    // turn on display FPS
    pDirector->setDisplayFPS(true);

    // pDirector->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);

    // create a scene. it's an autorelease object
    CCScene *pScene = HelloWorld::scene();

    // run
    pDirector->runWithScene(pScene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->pause();

    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->resume();

    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

AppDelegate.h

#ifndef  _APP_DELEGATE_H_
#define  _APP_DELEGATE_H_

#include "CCApplication.h"

/**
@brief  The cocos2d Application.

The reason for implement as private inheritance is to hide some interface call by CCDirector.
*/
class  AppDelegate : private cocos2d::CCApplication
{
public:
    AppDelegate();
    virtual ~AppDelegate();

    /**
    @brief  Implement for initialize OpenGL instance, set source path, etc...
    */
    virtual bool initInstance();

    /**
    @brief  Implement CCDirector and CCScene init code here.
    @return true    Initialize success, app continue.
    @return false   Initialize failed, app terminate.
    */
    virtual bool applicationDidFinishLaunching();

    /**
    @brief  The function be called when the application enter background
    @param  the pointer of the application
    */
    virtual void applicationDidEnterBackground();

    /**
    @brief  The function be called when the application enter foreground
    @param  the pointer of the application
    */
    virtual void applicationWillEnterForeground();
};

#endif // _APP_DELEGATE_H_

HelloWorldScene.cpp

#include "HelloWorldScene.h"
#include "JNISharedObject.h"
USING_NS_CC;

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::node();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::node();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    CCMenuItemImage *pCloseItem = CCMenuItemImage::itemFromNormalImage(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback) );
    pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );

    // create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, NULL);
    pMenu->setPosition( CCPointZero );
    this->addChild(pMenu, 1);

    /////////////////////////////
    // 3. add your codes below...

    // add a label shows "Hello World"
    // create and initialize a label
    CCLabelTTF* pLabel = CCLabelTTF::labelWithString("Hello World", "Thonburi", 34);

    // ask director the window size
    CCSize size = CCDirector::sharedDirector()->getWinSize();

    // position the label on the center of the screen
    pLabel->setPosition( ccp(size.width / 2, size.height - 20) );

    // add the label as a child to this layer
    this->addChild(pLabel, 1);

    // add "HelloWorld" splash screen"
    CCSprite* pSprite = CCSprite::spriteWithFile("HelloWorld.png");

    // position the sprite on the center of the screen
    pSprite->setPosition( ccp(size.width/2, size.height/2) );

    // add the sprite as a child to this layer
    this->addChild(pSprite, 0);

    return true;
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    JNISharedObject::Inst()->unlockAchievement("1144912 ");
}

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommand to return the exactly class pointer
    static cocos2d::CCScene* scene();

    // a selector callback
    virtual void menuCloseCallback(CCObject* pSender);

    // implement the "static node()" method manually
    LAYER_NODE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

InitJNIFunctions.cpp

/*
 * InitJNIFunctions.cpp
 *
 *  Created on: Jul 25, 2011
 *      Author: beejay
 */

#include "InitJNIFunctions.h"
#include "JNISharedObject.h"

JNIEXPORT void JNICALL Java_org_cocos2dx_testgame_testgame_initCallbacks(JNIEnv*  env, jobject thiz)
{
    __android_log_write(ANDROID_LOG_ERROR,"Test","Message");
    JNISharedObject::sharedEnv = env;
    JNISharedObject::obj = thiz;
    JNISharedObject::jcls = env->GetObjectClass(thiz);
}

InitJNIFunctions.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class org_cocos2dx_PitCrewCombine_PitCrewCombine */

#ifndef _Included_org_cocos2dx_testgame_testgame
#define _Included_org_cocos2dx_testgame_testgame
#ifdef __cplusplus
extern "C" {
#endif
#undef org_org_cocos2dx_testgame_testgame_HANDLER_SHOW_DIALOG
#define org_org_cocos2dx_testgame_testgame_HANDLER_SHOW_DIALOG 1L
/*
 * Class:     org_cocos2dx_PitCrewCombine_PitCrewCombine
 * Method:    initCallbacks
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_org_cocos2dx_testgame_testgame_initCallbacks
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
/* Header for class org_cocos2dx_PitCrewCombine_PitCrewCombine_LoginDialogListener */

#ifndef _Included_org_cocos2dx_testgame_testgame_LoginDialogListener
#define _Included_org_cocos2dx_testgame_testgame_LoginDialogListener
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class org_cocos2dx_PitCrewCombine_PitCrewCombine_WallPostDialogListener */

#ifndef _Included_org_cocos2dx_testgame_testgame_WallPostDialogListener
#define _Included_org_cocos2dx_testgame_testgame_WallPostDialogListener
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

JNISharedObject.cpp

/*
 * JNISharedObject.cpp
 *
 *  Created on: Jul 16, 2011
 *      Author: beejay
 */
#include "JNISharedObject.h"
#include 

JNISharedObject* JNISharedObject::pInstance = NULL;
JNIEnv* JNISharedObject::sharedEnv = NULL;
jclass JNISharedObject::jcls = NULL;
jobject JNISharedObject::obj = NULL;

JNISharedObject* JNISharedObject::Inst(){
  if(pInstance == NULL){
    pInstance = new JNISharedObject();
  }
  return pInstance;
}

void JNISharedObject::startFacebook(const char* share)
{
    jmethodID mid = sharedEnv->GetMethodID(jcls, "share", "(Ljava/lang/String;)V");
    if (mid == 0) return;
    sharedEnv->CallVoidMethod(obj, mid, sharedEnv->NewStringUTF(share));
}

void JNISharedObject::achievementList()
{
    jmethodID mid = sharedEnv->GetMethodID(jcls, "achievementList", "()V");
    if (mid == 0) return;
    sharedEnv->CallVoidMethod(obj, mid);
}

void JNISharedObject::leaderBoards()
{
    jmethodID mid = sharedEnv->GetMethodID(jcls, "leaderBoards", "()V");
    if (mid == 0) return;
    sharedEnv->CallVoidMethod(obj, mid);
}

void JNISharedObject::unlockAchievement(const char* id)
{
    jmethodID mid = sharedEnv->GetMethodID(jcls, "unlockAchievement", "(Ljava/lang/String;)V");
    if (mid == 0) return;
    sharedEnv->CallVoidMethod(obj, mid, sharedEnv->NewStringUTF(id));
}

JNISharedObject::JNISharedObject(){ // constructor

}

JNISharedObject.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#ifndef JNISHARED__
#define JNISHARED__

#include "cocos2d.h"
#include 
#include 
#include 
#include 
#include 
using namespace std;

#define kMaxUnlockedCars 50
#define kMaxCars 4
/* Header for class org_cocos2dx_PitCrewCombine_PitCrewCombine */



class JNISharedObject
{
    public:
        static JNISharedObject* Inst();
        void Logging(string message);
        void startFacebook(const char*);
        void achievementList();
        void unlockAchievement(const char* id);
        void leaderBoards();
        static JNIEnv* sharedEnv;
        static jobject obj;
        static jclass jcls;
        static JNISharedObject* pInstance;

        void loadValuesFromSaveFile();
        void saveValuesFromSaveFile();

        static float maComponentTimes[6];
        static float maPitStopTimes[10];
        static float maSkillJackTimes[4];
        static float maSkillTireTimes[4];
        static float maSkillFuelTimes[4];
        static int maUnlockedcars[kMaxUnlockedCars];
        static int maNewCars[kMaxUnlockedCars];
        static int nCarType;
        static bool bIsSoundOn;
        static bool bIsFirstPlay;

        static float bestOnlineScores[7];

        static int nPit11Secs3InARow;
        static int nPit15Secs5InARow;
        static int nPit12Secs5InARow;
        static int nCompletedPit;

        static int nGCWin;

        static bool bSkillGasDone;
        static bool bSkillJackDone;
        static bool bSkillTiresDone;

        static int nCarP1;
        static int nCarP2;

        static int nNightRacer;

        static int nNextScene;
        void Initialize();
        ~JNISharedObject();
    protected:
        JNISharedObject(); // constructor

};

#endif

Java Side: org.cocos2dx.testgame

testapp.java

package org.cocos2dx.testgame;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Application;
import android.util.Log;
import com.openfeint.api.OpenFeint;
import com.openfeint.api.OpenFeintDelegate;
import com.openfeint.api.OpenFeintSettings;
import com.openfeint.api.resource.Achievement;
import com.openfeint.api.resource.Leaderboard;

public class testapp extends Application {

    public static List achievements = null;
    public static List leaderboards = null;

    @Override
    public void onCreate() {
        super.onCreate();

        Map options = new HashMap();
        options.put(OpenFeintSettings.SettingCloudStorageCompressionStrategy, OpenFeintSettings.CloudStorageCompressionStrategyDefault);
        // use the below line to set orientation
        // options.put(OpenFeintSettings.RequestedOrientation, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        Log.e("Init Openfeint", "Settings Init");
        OpenFeintSettings settings = new OpenFeintSettings("PCC", "mRyz1yYCsOTH6KpLcK1IQ", "jy6vangncM4PkLQS1nw5KMRFBK3fCUoCMnV1VJ2PY", "332553", options);
        Log.e("Init Openfeint", "App init");
        OpenFeint.initialize(this, settings, new OpenFeintDelegate() { });

//        Achievement.list(new Achievement.ListCB() {
//          @Override public void onSuccess(List _achievements) {
//              achievements = _achievements;
//          }
//      });
//        
//        Leaderboard.list(new Leaderboard.ListCB() {
//          @Override public void onSuccess(List _leaderboards) {
//              leaderboards = _leaderboards;
//          }
//      });
    }

}

testgame.java

package org.cocos2dx.testgame;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.testgame.R;

import com.openfeint.api.resource.Achievement;

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;

public class testgame extends Cocos2dxActivity{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        // get the packageName,it's used to set the resource path
        String packageName = getApplication().getPackageName();
        super.setPackageName(packageName);
        initCallbacks();
        setContentView(R.layout.game_demo);
        mGLView = (Cocos2dxGLSurfaceView) findViewById(R.id.game_gl_surfaceview);

        // Get the size of the mGLView after the layout happens
        mGLView.post(new Runnable() {

            @Override
            public void run() {
                Cocos2dxActivity.screenHeight = mGLView.getHeight();
                Cocos2dxActivity.screenWidth = mGLView.getWidth();
            }
        });
    }
     public void unlockAchievement(String id)
        {
            final Achievement a = new Achievement(id);
            a.unlock(new Achievement.UnlockCB()
            {
                public void onSuccess(boolean newUnlock) {
                    Log.e("In Achievement", "Unlock");
                    a.notifyAll();
                }           
            });
        }
     @Override
     protected void onPause() {
         super.onPause();
         mGLView.onPause();
     }

     @Override
     protected void onResume() {
         super.onResume();
         mGLView.onResume();
     }

     private GLSurfaceView mGLView;

     static {
         System.loadLibrary("cocos2d");
         System.loadLibrary("cocosdenshion");
         System.loadLibrary("game");
     }

     private native void initCallbacks();
}

manifest File I’m Using

The warning I get

08-09 16:54:00.645: WARN/WindowManager(3461): Window Window{40af7920 org.cocos2dx.testgame/org.cocos2dx.testgame.testgame paused=false} destroyed surface Surface(name=org.cocos2dx.testgame/org.cocos2dx.testgame.testgame, identity=-1, mNativeSurface=0), session Session{40951cf8 uid 10174}
08-09 16:54:00.650: WARN/WindowManager(3461): Window Window{407dcb98 SurfaceView paused=false} destroyed surface Surface(name=SurfaceView, identity=-1, mNativeSurface=0), session Session{40951cf8 uid 10174}
08-09 16:54:00.680: WARN/SurfaceFlinger(3461): org.cocos2dx.testgame/org.cocos2dx.testgame.testgame[504] is not removed from mLayerMap
08-09 16:54:00.680: WARN/SurfaceFlinger(3461): SurfaceView[505] is not removed from mLayerMap

See that the window gets destroyed?
————

I know that native to java and vice-versa calls are working because I’ve tested this with calls that does not need to update the UI.

I hope you could look into this. I might be forced to port Cocos2d-x code to Cocos2d-android if no fix could be found, and that’s a lot of work.

Thanks.

Basically, I modified the close button to call an openfeint achievement.

I’m trying to do something similar, but instead of just unlock an achievement, I’m trying to switch to the sample OpenFeint application. What happens to me is I get an error message, saying the application closed unexpectedly.

Yes, I’ve done that too. I’ve done a lot of things actually. This does not occur on Openfeint only. List of things I’ve done:

  1. Facebook API, Facebook Post, Update UI thread using the following methods:
    ~~Async
    ~~Message Handler
    ~~Runnable thread via new Thread.
    Hit or Miss sometimes works, but most of the time it fails.
  2. Facebook API via new activity
    ~~ Doing this via Intent

Same thing.


What I’m seeing is that these problems occurs whenever we try to update the UI thread, or try to call a new Activity (As I think what Cesar was trying to do — calling the openfeint sample app).

Is this a bug? I just want to know.

do I need to add the sample app to my manifest?

Are you calling it as a new activity (using intent) , if yes, then you need to add it in the manifest as a new activity.

Anyone wants to take a whack at this? I would really appreciate your help. __

I would start looking inside the cocos2d-x code for now, I don’t know if this is a bug, but I’m hitting a dead end now.

Oh okay. Anyway, I didn’t set the exported property to true. After I did that, it worked when I used a custom action string. Well… worked meaning I didn’t get a NullPointerException, and instead got WIN.DEATH! or something to that effect.

Ah, you mean your compiling a separate APK for openfeint then calling that. I’ve tried that too, and that error happens to me too. T__T Hope we could find a viable solution. Please post to this thread if ever you got that path working for you.

My problem’s been resolved. I don’t know about yours though. I used implicit intent, and set exported to true. I also added a default configuration as per this person’s advice: http://stackoverflow.com/questions/4121450/activitynotfoundexception/6376624#6376624. After that, I could freely switch from my game’s main menu to openfeints sample app.

oh and I only used `activity` cause that’s what my supervisor wanted. why not go with a service?

Tried it that way. I have a facebook activity that I set as exported. The activity just loads a webview for facebook (facebook api). I get the following errors.

08-11 17:31:16.590: WARN/ActivityManager(3472): Activity pause timeout for HistoryRecord{40ae9e70 org.cocos2dx.PitCrewCombine/.PitCrewCombine}
08-11 17:31:16.590: WARN/ActivityManager(3472): Trying to launch org.cocos2dx.PitCrewCombine/.ShareOnFacebook
08-11 17:31:17.565: ERROR/lights(3472): write_int: path /sys/devices/virtual/misc/melfas_touchkey/brightness, value 2
08-11 17:31:17.565: WARN/PowerManagerService(3472): Timer 0x7->0x3|0x0
08-11 17:31:22.180: ERROR/InputDispatcher(3472): channel '409f6070 org.cocos2dx.PitCrewCombine/org.cocos2dx.PitCrewCombine.PitCrewCombine (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-11 17:31:22.180: ERROR/InputDispatcher(3472): channel '409f6070 org.cocos2dx.PitCrewCombine/org.cocos2dx.PitCrewCombine.PitCrewCombine (server)' ~ Channel is unrecoverably broken and will be disposed!
08-11 17:31:22.180: WARN/WindowManager(3472): Window Window{409f6070 org.cocos2dx.PitCrewCombine/org.cocos2dx.PitCrewCombine.PitCrewCombine paused=false} destroyed surface Surface(name=org.cocos2dx.PitCrewCombine/org.cocos2dx.PitCrewCombine.PitCrewCombine, identity=-1, mNativeSurface=0), session Session{40a706a8 uid 10123}
08-11 17:31:22.190: WARN/SurfaceFlinger(3472): org.cocos2dx.PitCrewCombine/org.cocos2dx.PitCrewCombine.PitCrewCombine[709] is not removed from mLayerMap

Well, in case I run into something, I’ll post it here, but to be honest, you’re probably better at this than I am. I mean, hell, one of the reasons I couldn’t get mine to work, besides not setting the exported value, is that I forgot to initialize my singleton of HelloWorld (I’m running static java methods, and apparently android requires an instance to call startService or startActivity).

:Sigh: The thing is, sometimes it works. I’m really clueless. I guess I’ll have to find some other way right now.

it’s not that your connection’s timing out?

Well, DDMS should say otherwise. I’ve also tested with activities that does not require connections (Tested with an activity that just displays a toast message), and it still fails.

Oh, and if you look at the error, an Activity pause timeout occurs, but that should not happen.

Oh, and I’m not better at this than you :slight_smile:

Cesar, could you post a sample code here, maybe I’m missing something. Thanks