Activity.SetContentView()について

1,237 views
Skip to first unread message

ryo

unread,
Jul 2, 2009, 9:25:30 AM7/2/09
to Android-SDK-Japan
こんにちは。
ryo@初投稿です。

初歩的な質問となってしまうかもしれないですが、
有識者の方、ご教授お願い致します。

Viewを継承した画面のキーイベントでActivity.SetContentView()を
呼び出すと、画面が更新されない場合があります。
画面は更新されておらず、例外も発生しておりません。

[条件]
1.BACKキーを押下してアプリをサスペンドさせる。
2.再度アプリを選択して、アプリを起動する。
3.Viewを継承した画面のキーイベントでActivity.SetContentView()を
 呼び出すと、画面が更新されない。
※HOMEキーなどでサスペンドした場合は、問題は発生しておらず、
 BACKキーやActivity.finish()で現象が発生します。


以上、宜しくお願い致します。

Daisuke Miyakawa

unread,
Jul 3, 2009, 2:44:06 AM7/3/09
to android-...@googlegroups.com
こんにちは
はじめまして、宮川です。

ryoさんのおっしゃる状況をテストするために一つテストプロジェクトを作成して確認してみました。以下に置いておきます。

http://mowa-net.jp/~amedama/tmp/SetContentViewTest.tar.gz

画面をタップするとCustomTextViewクラスが新しいオブジェクトを生成して親のActivityのsetContentViewを呼ぶことで見た目では数字がカウントされる、というものです。
おっしゃる状況を再現するほぼ最小の構成にしてあります。

上記のアプリケーションを試す限りですと、ryoさんがおっしゃる状況と異なり、
- BACKキーを押下
- 再度アプリを立ち上げ
- 画面をタップ
-> 数字は正しくカウントされる

と、

> 画面が更新されない場合があります。

というおっしゃる状況は起こりません。一応「更新」はされます。(もし私の理解が間違っているようであればご指摘願います)

ただし、BACKキーを押下した際、なぜか必ずonStop()どころかonDestroy()まで呼ばれてアプリケーションが完全に終了してしまうため、
アプリケーションの情報がすべて失われてしまいます。具体的には、カウントが1に必ず戻ってしまいます。

# Activity の状態遷移についてもしご存じなければ以下のページの図をご覧ください
# http://developer.android.com/reference/android/app/Activity.html

一方、HOME を押した際にはonDestroy()が呼ばれないため、Activityのステートは保存されています。

ryoさんの環境でも同様のことが起きていないかご確認いただけますか。

アプリケーション開発を行う立場から言うと、BACKやHOMEボタンでアプリケーションをバックグラウンドに押しやった場合には、
原則としてそのプロセスが殺される可能性が常にあるとお考えください。
『初めてのAndroid』という本によると、最悪、onDestroy()すら呼ばれない可能性があります。
(メモリが逼迫している環境で起こり得る問題です)

ですので、BACKなどを押された際に呼ばれるonPause()で、残しておきたい情報はすべて何らかのストレージに入れておくことをお勧めします。
例えば、今回私が作成したアプリケーションであれば、押下されたカウント数をonPause()時点でPreferenceに保存し、onResume()で読み出す、といった操作が良いかと思います。



後は予断になりますが、実装の面から言うと、BACKが押されただけでonDestroy()が呼ばれるのはちょっと不可思議ですし「むかつき」ますので、ちょっと調べてみます。何か分かればまたメールさせていただきます。

それでは失礼します m(_ _)m

2009/07/02 22:25 ryo <ryo.takaya...@gmail.com>:



--
Daisuke Miyakawa (宮川大輔)
d.miy...@gmail.com

ryo

unread,
Jul 3, 2009, 3:55:58 AM7/3/09
to Android-SDK-Japan
宮川さん

ご丁寧に回答いただき、ありがとうございます。
また、本来ならわたしのほうで用意すべきところ、
サンプルプログラムまで作っていただき、申し訳ございませんでした。

宮川さんにいただいたサンプルプログラムでは、
わたしの環境でも現象は発生しませんでした。
わたしがテストしていたプログラムと相違があり、
mViewをstaticとして使用していると問題が発生します。

staticとしているのは、onDestroy()でアプリが終了しても、
staticにしておけば終了前の状態を残せるので、終了前の描画状態を
表示する為に使用しております。
staticの利用方法が間違っているのでしょうか。

-----変更点は"//ryo"とコメントしている箇所となります-----
package com.android.example.setcontentviewtest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class SetContentViewTest extends Activity {

private int mCount;
//private CustomTextView mView;
static private CustomTextView mView;//ryo

@Override
protected void onCreate(Bundle savedInstanceState) {
//mView = new CustomTextView(this, 1);
if(mView == null)mView = new CustomTextView(this, 1); //ryo
super.onCreate(savedInstanceState);
setContentView(mView);
}

@Override
public void onStart() {
Log.d("@@@", "onPause()");
super.onStart();
}

@Override
public void onResume() {
Log.d("@@@", "onResume()");
super.onResume();
mView = new CustomTextView(this, mCount);
}

@Override
public void onPause() {
Log.d("@@@", "onPause()");
super.onPause();
mCount = mView.getCount();
//mView = null; // clear (for test) //ryo
}

@Override
public void onStop() {
Log.d("@@@", "onStop()");
super.onStop();
}

@Override
protected void onDestroy() {
Log.d("@@@", "onDestroy()");
super.onDestroy();
}
}
---------------------------------------------------------

以上、宜しくお願い致します。

Daisuke Miyakawa

unread,
Jul 3, 2009, 5:11:08 AM7/3/09
to android-...@googlegroups.com
ryoさん

ご返答ありがとうございます。状況を理解しました。

static で Viewオブジェクトを作っていても、それが参照しているContextオブジェクト(多分Activityですね)はstaticとは絶対になりえないので、

- mView は static にしていても。。。
- mView が参照している Context object (Activity object) は static ではない
- mView が参照している Context object (Activity object) は destroy される
- mView も壊れる

という感じで理解していただくのが良いかな、と思います。実装は…実際のコードをご覧ください(^^;

#もし上記の理解で間違いがあれば訂正願います > experts

Activity は、Androidの本体によって勝手に破棄されます。これを防ぐ方法は、基本的には「ない」とご理解ください。それらを(ある意味)親として持っている各widget (View や EditTextなど)は
すべて static にしない方がよいです。それぞれのViewの状態を保存しておくのであれば、Preferenceといったストレージを使わないと、多分同じ問題が起こると思います。

もし分からないことがあればまたご返答ください。

それでは。

2009/07/03 16:55 ryo <ryo.takaya...@gmail.com>:

ryo

unread,
Jul 3, 2009, 6:32:10 AM7/3/09
to Android-SDK-Japan
宮川さん

ご回答ありがとうございました。

やっと理解出来ました。

Activityが破棄されるとViewも壊れてしまうんですね。
onDestroy()後のonCreate()では、setContentView()は動作しているのに
その後のsetContentView()はうまく動かないところが、ちょっと不思議
ですが、onDestroy()にstatic obujectを使用するのは、やめようと
思います。

ご丁寧にありがとうございました。
Reply all
Reply to author
Forward
0 new messages