如何在屏幕旋转上存储大量数据?

How to store lots of data upon Screen Rotation?

是的,我已经阅读了很多其他帖子,但我无法跟进,因为我有很多变量,而不仅仅是一两个。

我第一次制作支持横屏的应用程序(TIC TAC TOE)。我正在丢失有关屏幕旋转的数据。

package com.netlify.krupesh.tictactoe;

import android.graphics.Typeface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    // 0 for zero and 1 for X
    // 2 for empty
    boolean gameActive = true;
    int[] gameState = {2,2,2,2,2,2,2,2,2};
    int[][] winningPositions = {{0,1,2}, {3,4,5}, {6,7,8}, {0,3,6}, {1,4,7}, {2,5,8}, {0,4,8}, {2,4,6}};

    int activePlayer = 0;
    int[] playerScores = {0,0};

    // Show Symbol on Tap
    public void showSymbol(View view){
        // Set Player Scores
        TextView player1 = (TextView) findViewById(R.id.p1Score);
        TextView player2 = (TextView) findViewById(R.id.p2Score);


        player1.setText(playerScores[0]+"");
        player2.setText(playerScores[1]+"");

        // Get Symbol Info
        ImageView symbol = (ImageView) view;
        int tappedSymbol = Integer.parseInt(symbol.getTag().toString());

        // Update Game state Array
        if(gameState[tappedSymbol]==2 && gameActive) {
            gameState[tappedSymbol] = activePlayer;

            // Show Symbol with Animation
            symbol.setAlpha(0f);
            if (activePlayer == 0) {
                symbol.setImageResource(R.drawable.zero);
                activePlayer = 1;
                showCurrentPlayer(2);

            } else {
                symbol.setImageResource(R.drawable.cross);
                activePlayer = 0;
                showCurrentPlayer(1);
            }
            symbol.animate().alpha(1).setDuration(400);

            checkDraw(gameState);

            for (int[] winningPosition : winningPositions) {
                if (gameState[winningPosition[0]] == gameState[winningPosition[1]] && gameState[winningPosition[1]] == gameState[winningPosition[2]] && gameState[winningPosition[0]] != 2) {
                    showCurrentPlayer(0);
                    // Pause The Game
                    gameActive = false;

                    // Won the Game
                    String winningPlayer ;
                    if (gameState[winningPosition[0]] == 0) winningPlayer = "Player 1";
                    else winningPlayer = "Player 2";
                    Toast.makeText(this, winningPlayer + " won!", Toast.LENGTH_SHORT).show();

                    // Update Scores
                    playerScores[gameState[winningPosition[0]]]++;
                    player1.setText(playerScores[0] + "");
                    player2.setText(playerScores[1] + "");
                }
            }
        }
    }


    public void resetBoard(View view){
        android.support.v7.widget.GridLayout board = (android.support.v7.widget.GridLayout)findViewById(R.id.gridLayout);
        for(int i=0; i<board.getChildCount(); i++) {
            ImageView symbol = (ImageView) board.getChildAt(i);
            symbol.setImageDrawable(null);
        }
        for(int i=0; i<gameState.length; i++ ){
            gameState[i] = 2;
        }
        gameActive = true;
        activePlayer = 0;
        showCurrentPlayer(1);
    }

    public void checkDraw(int[] gamestate){
        for(int i =0; i<gamestate.length; i++){
            if(gamestate[i]==2){
                return;
            }
        }
        showCurrentPlayer(0);
        Toast.makeText(this, "Match Draw!", Toast.LENGTH_SHORT).show();
    }

    public void resetAll(View view){
        resetBoard(view);
        playerScores[0]=0; playerScores[1]=0;
        TextView player1 = (TextView) findViewById(R.id.p1Score);
        TextView player2 = (TextView) findViewById(R.id.p2Score);
        player1.setText(playerScores[0] + "");
        player2.setText(playerScores[1] + "");
        showCurrentPlayer(1);
    }

    public void showCurrentPlayer(int i){
        TextView player1Heading = (TextView) findViewById(R.id.subheading1);
        TextView player2Heading = (TextView) findViewById(R.id.subheading2);
        if(i==1){
            player1Heading.setTextColor(getResources().getColor(R.color.colorPlayer1));
            player1Heading.setTypeface(null, Typeface.BOLD);
            player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
            player2Heading.setTypeface(null, Typeface.NORMAL);
        }
        if(i==2){
            player2Heading.setTextColor(getResources().getColor(R.color.colorPlayer2));
            player2Heading.setTypeface(null, Typeface.BOLD);
            player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
            player1Heading.setTypeface(null, Typeface.NORMAL);
        }
        if(i==0){
            player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
            player1Heading.setTypeface(null, Typeface.NORMAL);
            player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
            player2Heading.setTypeface(null, Typeface.NORMAL);
        }
    }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ===================== Hide Status Bar ========================== //
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // ================================================================ //

        setContentView(R.layout.activity_main);
        showCurrentPlayer(1);
    }
}

看,有这么多东西.. 对于所有 ImageView,我需要保存谁设置了他们的图像。现在我该如何解决这个旋转问题??

添加代码片段的解决方案最有帮助,新手 Android 开发

@krupesh Anadkat 作为新手,我感到很沮丧,但 @CommonsWare 是一位经验丰富的开发人员,已经在游戏中玩了好几天了.

听从他的建议,确保你学习了他概述的基础知识,而不是盲目学习或只是为了它而匆忙构建一些东西。

然而今天是你的幸运日,所以我会用一些代码片段来宠坏你(我们千禧一代的程序员喜欢它简单 - 是的,我说过!!!)继续阅读并学习。

您在这里遇到的问题是设备配置更改。

在您的情况下,屏幕方向 发生了变化。

每次用户旋转该屏幕时,Android OS 都会重新创建您的 activity[=56= 】 一个新的。 Android OS 意味着没有任何危害,它只是试图提高效率,因为它检查是否有更好的资源用于新方向,如果有,它可以使用那些相反。

这就是你痛苦的根源。现在让我们开始并帮助你成为伙伴。

您可以使用 Activity 的 class 方法来解决这个问题。在全能的 Android OS 杀死你的 Activity 之前,方法 onSaveInstanceState() 将在你的Activity 的生命周期。在您的 class 中,您覆盖 onSaveInstanceState() 并将您想要的数据保存到 Bundle 其中 onSaveInstanceState() 作为参数。

然后在你的 Activity 的 onCreate() 你检查 savedInstanceState 是否不为空如果它不为空你检索您的数据。

不过要小心;最好将原始数据类型保存到Bundle可序列化的对象以避免检索数据已过时,即已过时或不再有效。

请参阅下面我的 SaveDataAcrossScreenOrientation Activity 的代码片段

package com.demo.android.savedataacrossscreenrotationdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SaveDataAcrossScreenOrientation extends AppCompatActivity {

    // Key to be used for the key: value pair to be saved to the bundle
    private static final String KEY_GREETING_TEXT = "greeting_text";

    // The text currently displayed to the screen
    private String mCurrentDisplayedText;

    private TextView mGreetingTextView;
    private Button mSpanishButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get references to the button and textview
        mGreetingTextView = (TextView) findViewById(R.id.greeting_text_view);
        mSpanishButton = (Button) findViewById(R.id.change_greeting_button);

        // If mCurrentDisplayedText is inside the bundle retrieve and display it on screen
        if(savedInstanceState != null) {
            mCurrentDisplayedText = savedInstanceState.getString(KEY_GREETING_TEXT, "");
            if (mCurrentDisplayedText != "") {
                mGreetingTextView.setText(mCurrentDisplayedText);
            }
        }

        // Set a listener on the spanish button
        mSpanishButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Change the english text to spanish when the button is clicked
                mGreetingTextView.setText(R.string.spanish_greeting);

                // Get the text currently shown in the text view
                mCurrentDisplayedText = (String) mGreetingTextView.getText(); // Calling getText() returns a CharSequence cast it to a string
            }
        });
    }

    // Override onSaveInstanceState(Bundle savedInstanceState) and save mCurrentDisplayedText to the bundle
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putString(KEY_GREETING_TEXT, mCurrentDisplayedText);
    }

}

See video demo here

玩得开心!