[Android game development 19th] (required) SurfaceView Operation Mechanism

Source: Internet
Author: User

 

 

For background operations, such as clicking the HOME button and clicking the return button...

 

When the program is restarted, an exception is reported. Surfaceiew reports two exceptions:

 

First, an error occurred while submitting the canvas! For example, (simulator error prompt and Logcat Detail)

 


 

 

 

Solution code:

 

 

··· · 50 ······· · 90 ····· · 140 · 150

Public void draw (){

Try {

Canvas = sfh. lockCanvas ();

If (canvas! = Null ){

Canvas. drawColor (Color. WHITE );

Canvas. drawBitmap (bmp, bmp _x, bmp _y, paint );

}

} Catch (Exception e ){

Log. v ("Himi", "draw is Error! ");

} Finally {// Note 1

If (canvas! = Null) // Note 2

Sfh. unlockCanvasAndPost (canvas );

}

}

 

First, let's take a look at note 1. in the previous article, I explained why sfh. unlockCanvasAndPost (canvas) should be written in finally, mainly to ensure that images can be submitted normally.

Cloth. Today I will talk about remark 2. Check whether the canvas is empty, because canvas cannot be obtained when the program enters the background! If the canvas is empty, submit the painting.

A parameter Exception error occurs!

 

 

The following is another case: thread startup exception! For example, (simulator error prompt and Logcat Detail)

 

 

 

This exception is only reported when you click the Home button during the program running and enter the program again. The exception indicates that our thread has been started! Why is the return button okay?

 

OK. Next we will explain in detail the Back and Home buttons in Android! Analyze the problem and solve the problem!

 

First look at the Code in the following MySurfaceViewAnimation. java class:

 

 

··· · 50 ······· · 90 ····· · 140 · 150

Public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {

Private Thread th;

Private SurfaceHolder sfh;

Private Canvas canvas;

Private Paint paint;

Private Bitmap bmp;

Private int BMP _x, BMP _y;

Public MySurfaceViewAnimation (Context context ){

Super (context );

This. setKeepScreenOn (true );

Bmp = BitmapFactory. decodeResource (getResources (), R. drawable. himi_dream );

Sfh = this. getHolder ();

Sfh. addCallback (this );

Paint = new Paint ();

Paint. setAntiAlias (true );

This. setLongClickable (true );

Th = new Thread (this, "himi_Thread_one ");

Log. e ("Himi", "MySurfaceViewAnimation ");

}

Public void surfaceCreated (SurfaceHolder holder ){

Th. start ();

Log. e ("Himi", "surfaceCreated ");

}

Public void surfaceChanged (SurfaceHolder holder, int format, int width, int height ){

Log. e ("Himi", "surfaceChanged ");

}

Public void surfaceDestroyed (SurfaceHolder holder ){

Log. e ("Himi", "surfaceDestroyed ");

}

Public void draw (){

Try {

Canvas = sfh. lockCanvas ();

If (canvas! = Null ){

Canvas. drawColor (Color. WHITE );

Canvas. drawBitmap (bmp, bmp _x, bmp _y, paint );

}

} Catch (Exception e ){

Log. v ("Himi", "draw is Error! ");

} Finally {// Note 1

If (canvas! = Null) // Note 2

Sfh. unlockCanvasAndPost (canvas );

}

}

Public void run (){

While (true ){

Draw ();

Try {

Thread. sleep (100 );

} Catch (Exception ex ){

}

}

}

}

 

 

The above is our commonly used custom SurfaceView, and the old framework that uses the Runnable interface is not much to talk about. Among them, I add printing to the construction, creation, state change, and extinction functions of this class!

OK. See the first figure below: (the program is just running)

 

 

The left part of is Dubug! A thread is running, and its name is himi_Thread_one ";

 

The left part is the LogCat log! As you can see clearly, when you first enter the program, you will first enter the view constructor, then create the view, and then change the view status and OK. We all know this!

 

Next I will click the Home button! At this time, the program is in the background! Then re-enter the program process!

 

We can see that our thread is still one. Here we mainly observe the process from clicking home to entering the program again: (the process is as follows ):

Click home and call view destruction. after entering the program, the view will be created first, and the view status will change!

 

The above process is easy to understand. An important role is playing ~ Back button! Click Back to see what happened!

 

 

First look at the Debug column on the left, with one more thread! You can see that LogCat calls one more constructor than clicking the Home button!

 

 

Well, from the program we tested, there is no doubt that when you click Home and click Back to enter the program again, the steps are different and the number of threads has changed!

 

Here, we can explain why the Back button is not abnormal and the Home button is abnormal!

 

Cause: When you click the Back button to enter the program again, the view constructor is first entered. That is to say, a new thread is created and started! However, clicking Home is different, because clicking home again does not enter the constructor, but directly enters view to create this function, in the view creation function, we have a startup thread operation. In fact, the thread that started the program for the first time is still running. so ~ It must be abnormal here, that the thread has been started!

 

Some kids will ask, why don't we just put th = new Thread (this, "himi_Thread_one"); in the view creation function ??!!

Yes, you can! But when you repeat several times, you find that there will be many more processes in your program! (For example)

 

 

Although the thread startup exceptions can be avoided, this is obviously not the expected result!

 

 

The following describes the most suitable solution:

 

Modify MySurfaceViewAnimation. java

 

 

Public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {

Private Thread th;

Private SurfaceHolder sfh;

Private Canvas canvas;

Private Paint paint;

Private Bitmap bmp;

Private int BMP _x, BMP _y;

Private boolean himi; // Note 1

Public MySurfaceViewAnimation (Context context ){

Super (context );

This. setKeepScreenOn (true );

Bmp = BitmapFactory. decodeResource (getResources (), R. drawable. himi_dream );

Sfh = this. getHolder ();

Sfh. addCallback (this );

Paint = new Paint ();

Paint. setAntiAlias (true );

This. setLongClickable (true );

Log. e ("Himi", "MySurfaceViewAnimation ");

}

Public void surfaceCreated (SurfaceHolder holder ){

Himi = true;

Th = new Thread (this, "himi_Thread_one"); // Note 2

Th. start ();

Log. e ("Himi", "surfaceCreated ");

}

Public void surfaceChanged (SurfaceHolder holder, int format, int width, int height ){

Log. e ("Himi", "surfaceChanged ");

}

Public void surfaceDestroyed (SurfaceHolder holder ){

Himi = false; // Note 3

Log. e ("Himi", "surfaceDestroyed ");

}

Public void draw (){

Try {

Canvas = sfh. lockCanvas ();

If (canvas! = Null ){

Canvas. drawColor (Color. WHITE );

Canvas. drawBitmap (bmp, bmp _x, bmp _y, paint );

}

} Catch (Exception e ){

Log. v ("Himi", "draw is Error! ");

} Finally {

If (canvas! = Null)

Sfh. unlockCanvasAndPost (canvas );

}

}

Public void run (){

While (himi) {// Note 4

Draw ();

Try {

Thread. sleep (100 );

} Catch (Exception ex ){

}

}

}

}

 

 

 

The changes here are as follows:

 

1. we all know that after a thread is started, the thread will be destroyed as long as the run method is executed, so I added a Boolean member variable himi (note 1 ), here we can control a switch where our threads die! (Note 4)

2. Before starting the thread, set this Boolean value to true to keep the thread running.

3. When the view is destroyed, set this Boolean value to false to destroy the current thread! (Note 3)

 

OK. The figure and explanation here are detailed enough. I hope you will be sure to keep the Code strictly when developing a game in the future ~

 

Himi original, you are welcome to reprint, please note clearly! Thank you.

Address: http://blog.csdn.net/xiaominghimi/archive/2011/01/18/6149816.aspx

 

 

Here, I 'd like to apologize to all of you! I will explain: the source code will be included when I explain it to you, but the source code is a Demo code, so that you can see it clearly, so I will try to delete some irrelevant ones, but I found that the Demo code was followed by some children's shoes. As a result, many children's shoes asked me why I entered the background again after the program was executed and reported an exception! (Here I will give a full explanation of the operating mechanism. I hope you will be able to solve similar problems in the future ~)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.