Surface Created从未调用过,因此线程永远不会运行? [英] Surface Created never called and so the thread never runs?

查看:478
本文介绍了Surface Created从未调用过,因此线程永远不会运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很长一段时间以来,我一直在努力解决这个问题.

我的应用程序代码基于经过修改的月球着陆器.我有一个初始屏幕,然后显示一个菜单屏幕,启动我的主要活动.

在我的应用程序中,我有一个claSS游戏,该游戏已在main.xml中声明如下:-

我正在粘贴xml文件的一部分:-

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:-

<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>



我正尝试通过我的应用程序的MainActivity扩展此活动,如下所示:-

与月球着陆器不同,我的线程是与主要活动分开的类.



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.

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();


我创建了一个线程,该线程的定义在一个单独的文件中,但是被声明为Game类的一部分.
我面临的问题是为我的Game类创建的表面永远不会被调用,因此线程永远不会运行.

下面我粘贴游戏类


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

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) {
                }
            }



        }

推荐答案

来自
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.


这篇关于Surface Created从未调用过,因此线程永远不会运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆