●画面回転などで消える変数


アンドロイドのアプリを作っていざ実際の機械で動かしてみて、画面を回転させると、
テキストボックスに入れた値や、変数の値、ボタンの設定などがすべてリセットされてしまいます。
そして、onCreateからもう一度走り出します。
これはなんなんだろう?と思いきや、平常の動作らしいのですが、パソコンなどのアプリケーションを
書いている人たちから見るとえっ!という感じでしょうか。

そこで、まずはクラスの中にstaticなintと通常のintを入れてボタンを押すことによりカウントアップする
プログラムを作ってみます。



public class MainActivity extends AppCompatActivity {

    static int i;
    int j;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        android.widget.Button button=(android.widget.Button)findViewById(R.id.button);
        button.setOnClickListener(new button_listener());
        android.widget.TextView t1=(android.widget.TextView)findViewById(R.id.textView1);
        android.widget.TextView t2=(android.widget.TextView)findViewById(R.id.textView2);
        t1.setText(String.valueOf(i));
        t2.setText(String.valueOf(j));
    }

    private class button_listener implements android.view.View.OnClickListener {
        public void onClick(android.view.View view) {
            i++;
            j++;
            android.widget.TextView t1=(android.widget.TextView)findViewById(R.id.textView1);
            android.widget.TextView t2=(android.widget.TextView)findViewById(R.id.textView2);
            t1.setText(String.valueOf(i));
            t2.setText(String.valueOf(j));
        }
    }
}


このプログラムをスマートフォンで動作させてボタンを押してみました。




次に横向きにしてみました。



横向きにすると通常の変数がリセットされて 0 になってしまいます。
しかしstaticな変数は値を保持しています。

staticなint変数なら値を保持できるとしたらstaticな変数にクラスを入れてそこに色々な値を保存すれば
うまくいくのではないかと思い作成したのが次のプログラムです。
class testがデータを保持すると仮定したクラスです。



public class MainActivity extends AppCompatActivity {

    static test _test;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        android.widget.Button button=(android.widget.Button)findViewById(R.id.button);
        button.setOnClickListener(new button_listener());

        if(null==_test){
            _test=new test();
        }

        android.widget.TextView t1=(android.widget.TextView)findViewById(R.id.textView1);
        t1.setText(String.valueOf(_test.getInt()));

    }

    private class button_listener implements android.view.View.OnClickListener {
        public void onClick(android.view.View view) {
            _test.add();
            android.widget.TextView t1=(android.widget.TextView)findViewById(R.id.textView1);
            t1.setText(String.valueOf(_test.getInt()));
        }
    }
    private class test {
        int i;
        public int getInt(){
            return i;
        }
        public void add(){
            i++;
        }

    }
}



上のプログラムを実行してみました。



スマートフォンを横に向けてみると、



staticな変数にnewしたクラスの値は保持されています。
次に変数やテキストボックスの値などが破棄される直前を捉えることができれば、
破棄される直前に画面周りの値や変数の値を保存して、
再び onCreate が走り始めたときに復元すればよさそうです。

そこで以下のようなメソッドをクラスの中に加えました。

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //画面にメッセージを表示する
        android.content.Context context = getApplicationContext();
        android.widget.Toast t=android.widget.Toast.makeText(context, "破棄されました", android.widget.Toast.LENGTH_LONG);
        t.show();
    }

onSaveInstanceStateは破棄されるときに呼び出されるそうですので、
画面を縦横に向けると、メッセージが表示されます。



onSaveInstanceStateが呼び出された時に画面周りや変数の値をstaticな変数にバックアップして
onCreateが走り始めた時に復元すればよさそうです。





▲トップページ > android