如何正确恢复应用程序

时间:2017-07-02 02:25:58

标签: android multithreading surfaceview

我是Android和线程新手。

什么应用程序

我有一个简单的应用程序,只显示在屏幕边界内弹跳的位图(即如果位图击中屏幕的右边缘,它将反转方向)。

问题

应用程序冻结,当我最小化它,有时需要很长时间加载,当它加载时,我看到一个黑屏。

问题

请尝试运行代码,它只是下面显示的一个文件,我只使用SurfaceView作为布局。在应用程序的功能方面没有什么先进的。 我很困惑为什么我们需要使用SurfaceHolder.Callback匿名类(在嵌套的SurfaceView类中的方法中使用),如果我写的生命周期方法在嵌套的SurfaceView类中称为暂停,恢复和停止由主要活动的onPause,onResume,onStop方法调用。显示整个代码,然后显示app的结构,以查看我所做的概述,因为我没有看到SurfaceHolder.Callback方法的要点所以我的意思是我不知道为什么我们需要使用surfaceCreated, surfaceChanged,surfaceDestroyed,我不知道在surfaceChanged中放入什么。我还有一个onSaveInstanceSate和onRestoreInstance状态方法,只保存位图的x和y坐标。

public class MainActivity extends Activity {

GameView gameView;
Handler myHandler;
int xPos = 0;
int yPos = 0;
int deltaX = 3;
int deltaY = 3;
int iconWidth;
int iconHeight;

static final String STATE_POS_X = "playerPosX";
static final String STATE_POS_Y = "playerPosY";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    myHandler = new Handler ();
    gameView = new GameView(this);
    setContentView(gameView);
}

class GameView extends SurfaceView {

    private SurfaceHolder surfaceHolder;
    private Bitmap bmpIcon;
    private MyThread myThread;

    volatile boolean playingGame = true;

    public GameView(Context context) {
        super(context);
        init();
    }

    public GameView(Context context,
                         AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GameView(Context context,
                         AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init(){

        myThread = new MyThread(this);

        surfaceHolder = getHolder();
        bmpIcon = BitmapFactory.decodeResource(getResources(),
                R.drawable.rubberBall);

        iconWidth = bmpIcon.getWidth();
        iconHeight = bmpIcon.getHeight();

        surfaceHolder.addCallback( new SurfaceHolder.Callback(){

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                myThread.setRunning(true);
                myThread.start();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder,
                                       int format, int width, int height) {
                // What do I enter here???

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                boolean retry = true;
                myThread.setRunning(false);
                while (retry) {
                    try {
                        myThread.join();
                        retry = false;
                    } catch (InterruptedException e) {
                    }
                }
            }});
    }

    protected void drawSomething(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(bmpIcon,
                getWidth()/2, getHeight()/2, null);

        xPos += deltaX;
        if(deltaX > 0){
            if(xPos >= getWidth() - iconWidth){
                deltaX *= -1;
            }
        }else{
            if(xPos <= 0){
                deltaX *= -1;
            }
        }

        yPos += deltaY;
        if(deltaY > 0){
            if(yPos >= getHeight() - iconHeight){
                deltaY *= -1;
            }
        }else{
            if(yPos <= 0){
                deltaY *= -1;
            }
        }

        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(bmpIcon,
                xPos, yPos, null);

    }

    public void pause() {
        playingGame = false;
        try {
            myThread.join();
        } catch (InterruptedException e) {
        }
    }

    public void resume() {
        playingGame = true;
        myThread = new MyThread(this);
        myThread.start();
    }

}//END INNER CLASS: GameView

class MyThread extends Thread {

    GameView myView;
    private boolean running = false;

    public MyThread(GameView view) {
        myView = view;
    }

    public void setRunning(boolean run) {
        running = run;
    }

    @Override
    public void run() {
        while (running){

            Canvas canvas = myView.getHolder().lockCanvas();

            if(canvas != null) {
                synchronized (myView.getHolder()) {
                    myView.drawSomething(canvas);
                }
                myView.getHolder().unlockCanvasAndPost(canvas);
            }

            try {
                this.sleep(30);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }//END WHILE
      }
}//END INNER CLASS: MyThread

/**
 * BELOW are Main Activity Life Cycle Call Back methods!
 *
 */
@Override
protected void onStop() {
    super.onStop();
    Log.d("onStop", "Main Activity's onStop called");
    while (true) {
        gameView.pause();
        break;
    }
    this.finish();
}

@Override
protected void onResume() {
    super.onResume();
    Log.d("onResume", "Main Activity's onResume called");
    gameView.resume();
}

@Override
protected void onPause() {
    super.onPause();
    Log.d("onPause", "Main Activity's onPause called");
    gameView.pause();
}

//save and restore state
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);

    // Save the user's current game state
    savedInstanceState.putInt(STATE_POS_X, xPos);
    savedInstanceState.putInt(STATE_POS_Y, yPos);
}

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    xPos = savedInstanceState.getInt(STATE_POS_X);
    yPos = savedInstanceState.getInt(STATE_POS_Y);
}

}//END CLASS: MainActivity

MainActivity的结构包含嵌套的SurfaceView类

MainActivity life cycle methods
--------------------------------
onCreate:
------------
-links up the layout which is the SurfaceView instance
-initialize variables

onPause:
---------
call the SurfaceView's custom pause method here in addition to calling the 
super's onPause

onStop:
------
call the SurfaceView's custom stop method here in addition to calling the 
super's onStop

onResume:
---------
call the SurfaceView's custom resume method here in addition to calling the 
super's onResume

  nested Thread class
  ------------------------
  run method to run SurfaceView

  nested class SurfaceView's life cycle methods
  -------------------------------------------------------
    pause method which pauses the worker thread 
    ---------------------------------------------
    stop the worker thread:

    stop method which stops the worker thread:
    -----------------------------------------
    stop the worker thread

    resume method which creates a new worker thread:
    ---------------------------------------------------
    make a new worker thread

    SurfaceHolder.Callback lifespan methods
    ***Why do we need to write the methods below if I have pause,
    resume stop already that will be called by the Main Activity's
    onXXX, respectively????
    ==========================================

    surfaceCreated:
    ---------------
    make a new worker thread

    surfaceChanged:
    ---------------
     What do I enter here??

    surfaceDestroyed:
    -----------------
    destroy current worker thread

    END of nested SurfaceView class

override onSaveInstanceState method:
------------------------------------
save the bitmap's position (x and y coordinates)

override onRestoreInstanceState method:
-----------------------------------------
restore the bitmap's position (x and y coordinates)

END of MainActivity 

1 个答案:

答案 0 :(得分:0)

检查非常好的解释,因为与使用自定义视图绘图或使用预定义的图形输入或GUI元素不同,SurfaceView可以更精细地控制图形。

http://blog.infrared5.com/2011/07/android-graphics-and-animation-part-ii-animation/