Click here to Skip to main content
15,890,186 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have been struggling with this issue since a long time.

My app code is based on lunar lander with modifications. I have got a splash screen which then displays a menu screen which launches my main activity.

In my App, I have a claSS Game which I have declared in the main.xml as follows:-

I am pasting the portion of the xml file:-

HTML
<horizontalscrollview xmlns:android="http://schemas.android.com/apk/res/android">
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <relativelayout>
    android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:removed="@drawable/desert"
        android:clipToPadding="true">

     <com.example.android.game>
      android:id="@+id/Game"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"/></com.example.android.game></relativelayout></horizontalscrollview>


I am trying to inflate this activity from my app's MainActivity as follows:-

Unlike lunar lander my thread is seperate class from the Main activity.

Java
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);

        mGame = (Game) findViewById(R.id.Game);
        mGameThread = mGame.getThread();

I have created a thread the definition of which is in a seperate file but but which is declared as part of Game class..

The problem I am facing is that the surfacecreated for my Game class is never called.So the thread never runs.

Below I am pasting the Game Class

Java
public class Game extends SurfaceView implements SurfaceHolder.Callback{

     private int mX;
     private int mY;
     private int mSpeedX;
     private int mSpeedY;
     private Bitmap mBitmap;

     private GameThread thread;

     public static Context mContext;

     private TextView mStatusText;

     private boolean mSurfaceExists;

     public Game(Context context)
     {
         super(context);
           SurfaceHolder holder = getHolder();
         holder.addCallback(this);  

         // create thread only; it's started in surfaceCreated()
         Log.w(this.getClass().getName(),"Before thread create");
         thread = new GameThread(holder, context, new Handler() {

             @Override
             public void handleMessage(Message m) {
                 Log.w(this.getClass().getName(),"In Handle message");
                  mStatusText.setVisibility(m.getData().getInt("viz"));
                    mStatusText.setText(m.getData().getString("text"));
                }


         });

         setFocusable(true); // make sure we get key events

     }

     public Game(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         SurfaceHolder holder = getHolder();
         holder.addCallback(this);  

         // create thread only; it's started in surfaceCreated()
         Log.w(this.getClass().getName(),"Before thread create");
         thread = new GameThread(holder, context, new Handler() {

             @Override
             public void handleMessage(Message m) {
                 Log.w(this.getClass().getName(),"In Handle message");
                  mStatusText.setVisibility(m.getData().getInt("viz"));
                    mStatusText.setText(m.getData().getString("text"));
                }


         });

         setFocusable(true); // make sure we get key events

     }

     public Game(Context context, AttributeSet attrs) {
         super(context, attrs);
         // register our interest in hearing about changes to our surface
         SurfaceHolder holder = getHolder();
         holder.addCallback(this);  

         // create thread only; it's started in surfaceCreated()
         Log.w(this.getClass().getName(),"Before thread create");
         thread = new GameThread(holder, context, new Handler() {

             @Override
             public void handleMessage(Message m) {
                 Log.w(this.getClass().getName(),"In Handle message");
                  mStatusText.setVisibility(m.getData().getInt("viz"));
                    mStatusText.setText(m.getData().getString("text"));
                }


         });

         setFocusable(true); // make sure we get key events

     }


     /**
         * Fetches the animation thread corresponding to this LunarView.
         * 
         * @return the animation thread
         */
        public GameThread getThread() {
            return thread;
        }



        /**
         * Standard window-focus override. Notice focus lost so we can pause on
         * focus lost. e.g. user switches to take a call.
         */
        @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            if (!hasWindowFocus) thread.pause();
        }

        /**
         * Installs a pointer to the text view used for messages.
         */
        public void setTextView(TextView textView) {
            mStatusText = textView;
        }

     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // TODO Auto-generated method stub
            Log.w(this.getClass().getName(),":In surface changed");
         thread.setSurfaceSize(width, height);
        }
        public void surfaceCreated(SurfaceHolder arg0) {
            // TODO Auto-generated method stub

            // start the thread here so that we don't busy-wait in run()
            // waiting for the surface to be created
            mSurfaceExists = false;

            Log.w(this.getClass().getName(),"In Surface create");
            Log.w(this.getClass().getName(),":Before starting thread at create");
            thread.setRunning(true);
            thread.start();
        }

          /*
         * Callback invoked when the Surface has been destroyed and must no longer
         * be touched. WARNING: after this method returns, the Surface/Canvas must
         * never be touched again!
         */

        public void surfaceDestroyed(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
             // we have to tell thread to shut down & wait for it to finish, or else
            // it might touch the Surface after we return and explode
            boolean retry = true;
            mSurfaceExists = false;

            Log.w(this.getClass().getName(),"In Surface destroy");
            thread.setRunning(false);
            while (retry) {
                try {
                    thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }



        }
Posted

1 solution

from the doc of SurfaceHolder.Callback[^]

public abstract void surfaceCreated (SurfaceHolder holder)

This is called immediately after the surface is first created. Implementations of this should start up whatever rendering code they desire. Note that only one thread can ever draw into a Surface, so you should not draw into the Surface here if your normal rendering will be in another thread.


So your Thread-Handling might be the problem.
 
Share this answer
 
Comments
Nagy Vilmos 23-Sep-11 6:55am    
Good point.
ruchira biyani 25-Sep-11 23:03pm    
Hi TorstenH !!! Thanks for your suggestion!!! I am looking for a possible threading issue.Just a quick question. In my app I am first setting the view which sets the main User Interface.Then I am using the reference to the class from xml which uses surfaceview to start a thread which draws a ball dynamically on already existing UI.Do you think this approach has some flaw??
ruchira biyani 27-Sep-11 23:00pm    
I readin one of the forum that surfaceview does not work under horizontalscrollview.I guess this could be causing some issues.Here is the link for the same: http://stackoverflow.com/questions/6219473/ondraw-is-not-fired-nothing-is-drawn-in-surfaceview-android .But in my design , the horizontalscroll view is a must.Can anybody please help me and suggest some solution...
TorstenH. 28-Sep-11 16:09pm    
You have not read my answer. DO NOT start another Thread for creating GUI components. This is your problem - DO NOT USE THE OTHER THREAD.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900