In the code, I deleted all the declared variables and objects so as not to clutter up. When you press the power button off, super.Pause () is called and surfaceDestroy is not called. I decided to try to override the onPause () method and call destroy () through it. To do this, I in the class Menu must initialize an instance of the object of the class MainGamePanel. and call mMainGamePanel.gestroy (). If I do not initialize, the error Attempt to invoke virtual method 'void example.igeniy.MainGamePanel.destroy ()' on a null object reference will appear

Help to initialize and explain why this is so. Thank you. I will also be happy if you tell me why the power off button does not call the surfaceDestroyed method.

public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback { public MainGamePanel(Context context) { super(context); getHolder().addCallback(this); setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(TAG,"surfaceChanged"); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG,"surfaceCreated"); thread = new MainThread(getHolder(), this); thread.setRunning(true); thread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG,"surfaceDestroyed"); destroy(); } public synchronized void destroy(){ if(thread == null){ return; } boolean retry = true; thread.setRunning(false); while (retry){ try{ thread.join(); retry = false; } catch (InterruptedException ignored){ } } thread = null; } 

And another class:

 public class Menu extends AppCompatActivity { MainGamePanel mMainGamePanel = new MainGamePanel(просит ввести сюда Contex contect); //если дословно ввести Contex contex , то context горит красным (пишу это во избежание глупых советов) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new MainGamePanel(this)); } @Override protected void onPause() { super.onPause(); mMainGamePanel.destroy(); // вот что надо вызвать pause = false; Log.d(TAG, "onPause"); } } 
  • You cannot initialize View in the activity class field, at this stage there is no context yet - georgehardcore
  • Why can't you do it in a standard way? - georgehardcore
  • Are you asking why the surfaceDestroyed method surfaceDestroyed not automatically called? - georgehardcore
  • I do not understand what kind of standard way you are. Yes, the surfaceDestroyed method is not automatically called if I am off. screen power button. As a result, the stream continues to work with the screen off. But there is a home button to collapse, then everything is called right on the emulators, and if I try on the phone I do not remember what it is, the calls are not correct. - Turalllb

1 answer 1

You cannot initialize View in the activity class field, at this stage there is no context yet

What prevents to do ordinary?

Layout file (main.xml):

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.your.package.MainGamePanel android:id="@+id/main_game_panel" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 

Activity Code:

 public class Menu extends AppCompatActivity { private MainGamePanel mMainGamePanel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); mMainGamePanel = findViewById(R.id.main_game_panel); } @Override protected void onPause() { super.onPause(); mMainGamePanel.destroy(); // вот что надо вызвать pause = false; Log.d(TAG, "onPause"); } 

}

Or in your case:

 public class Menu extends AppCompatActivity { private MainGamePanel mMainGamePanel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mMainGamePanel = new MainGamePanel(this); setContentView(mMainGamePanel); } @Override protected void onPause() { super.onPause(); mMainGamePanel.destroy(); // вот что надо вызвать pause = false; Log.d(TAG, "onPause"); } } 
  • What is the difference between this setContentView (new MainGamePanel (this)); from this mMainGamePanel = new MainGamePanel (this); setContentView (mMainGamePanel); ? If nothing, then as a result I get the error MainGamePanel.destroy () 'on a null object reference. But it seems there is a difference .. In this case, we know the name of the instance we created or how more correctly to say what we have in this case? In the evening I will be at home and try - Turalllb
  • It would be interesting to know in what cases surfaceDestroyed is called, as you say, automatically. On some phones, it is called on some not with the same operations. And in general, I can not understand why the Back button calls the super.destroy () method and the whole application is killed .. - Turalllb
  • @Turalllb, the difference is that in the first case you have a link in the field will be null, and in the second there will be a link to the object and there will be no error, if it is not clear why read the basics of Android, in particular, the activity life cycle, at the same time you will find the answer to the second the question is georgehardcore
  • now destroy is turned on immediately after onPause. and earlier when folding after onStop. those. the game situation after turning off after a fraction of a second has stopped, if this is a quick game, then it will advance significantly during this time. and now it stops immediately, but after the onStop, the automatic method is also called, but this is not critical. Now turning off the screen forcibly calls the Destroy method, but when the screen is turned on, the surfaceCreated is not called, just like the Destroy was not called. you can also force it. But in the case of a simple collapse, it will be called twice. I think this is an exotic one - Turalllb
  • did not think ... it is impossible to create surfaceCreated, the mMainGamePanel.Created method (you need to write something here); there is nothing to write there because it comes from extends AppCompatActivity, and not extends SurfaceView. and how to be? How to start the stream again when the screen turns on? - Turalllb