findViewById()メソッドで強制終了してしまう

696 views
Skip to first unread message

Mika Pucca

unread,
Jun 5, 2014, 7:15:35 AM6/5/14
to android-g...@googlegroups.com
はじめまして。プッカと申します。
初投稿です。

現在、テキストを見ながらAndroidアプリ開発の勉強をしています。
しかし途中でつまってしまい今回、質問をさせていただきました。

findViewById()メソッドを使って文章を表示させるといった内容で、res⇒layout⇒fragment_test_view_activity2.xmlのidを@+id/myTextViewと設定し、TestViewActivity.javaに以下のようなソースを入力しました(青い部分が入力した部分です)。

・・・
import android.widget.TextView;

public class TestViewActivity2 extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_view_activity2);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
TextView myTextView = (TextView) findViewById(R.id.myTextView);
myTextView.setText("こんにちはAndroid");
 
}
・・・
これで実行すると『こんにちはAndroid』と表示されるはずが、エラーが出て強制終了してしまいます。

そこでLogCatを確認したところ以下のようなWarningとErrorが表示されていました。

・・・
06-05 10:22:33.021: W/dalvikvm(279): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
06-05 10:22:33.041: E/AndroidRuntime(279): FATAL EXCEPTION: main
06-05 10:22:33.041: E/AndroidRuntime(279): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testview2/com.example.testview2.TestViewActivity2}: java.lang.NullPointerException
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.os.Handler.dispatchMessage(Handler.java:99)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.os.Looper.loop(Looper.java:123)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread.main(ActivityThread.java:4627)
06-05 10:22:33.041: E/AndroidRuntime(279): at java.lang.reflect.Method.invokeNative(Native Method)
06-05 10:22:33.041: E/AndroidRuntime(279): at java.lang.reflect.Method.invoke(Method.java:521)
06-05 10:22:33.041: E/AndroidRuntime(279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-05 10:22:33.041: E/AndroidRuntime(279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-05 10:22:33.041: E/AndroidRuntime(279): at dalvik.system.NativeStart.main(Native Method)
06-05 10:22:33.041: E/AndroidRuntime(279): Caused by: java.lang.NullPointerException
06-05 10:22:33.041: E/AndroidRuntime(279): at com.example.testview2.TestViewActivity2.onCreate(TestViewActivity2.java:31)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
06-05 10:22:33.041: E/AndroidRuntime(279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
06-05 10:22:33.041: E/AndroidRuntime(279): ... 11 more
・・・

ネットで調べて色々、試してみましたがうまくいかず困っております。
初歩的なことで申し訳ございませんが、何かご助言をいただけますと幸いです。
宜しくお願い致します。

Hirokazu Fukami

unread,
Jun 5, 2014, 7:49:35 AM6/5/14
to android-g...@googlegroups.com
こんにちはfkmです。

@+id/myTextViewは、どのレイアウトXMLで設定していますか?
> --
> このメールは Google グループのグループ「日本Androidの会」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには
> android-group-j...@googlegroups.com にメールを送信してください。
> このグループに投稿するには android-g...@googlegroups.com にメールを送信してください。
> http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
> その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。



--
-------------------------------------------------------------
深見 浩和(Hirokazu Fukami)

URI:http://www.fkmsoft.jp
email: f...@fkmsoft.jp

Mika Pucca

unread,
Jun 5, 2014, 8:22:30 AM6/5/14
to android-g...@googlegroups.com
fkm様

早急なご回答ありがとうございます。

@+id/myTextViewは「fragment_test_view_activity2.xml」で設定しています。

テキストにはレイアウトファイルの「main.xml」で設定するよう記載されていますが、レイアウトファイルには「activity_test_view_activity2.xml」と「fragment_test_view_activity2.xml」の2つしかなく、@+id/myTextViewと入力してもエラーが出なかった「fragment_test_view_activity2.xml」に設定をしました。

suppi__

unread,
Jun 5, 2014, 8:26:37 AM6/5/14
to android-g...@googlegroups.com
suppi__です。

eclipseプロジェクトのcleanをしてみましたか?



2014年6月5日 20:49 Hirokazu Fukami <fkm...@gmail.com>:
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。

Hirokazu Fukami

unread,
Jun 5, 2014, 9:34:25 AM6/5/14
to android-g...@googlegroups.com
こんにちはfkmです。

>@+id/myTextViewは「fragment_test_view_activity2.xml」で設定しています。

このレイアウトXMLは、おそらくFragmentのonCreateView()内で
View root = inflater.inflate(R.layout.fragment_test_view_activity2,
container, false);
のようにしてViewにしていると思うので、ここで
root.findViewById(R.id.myTextView);
でTextViewを取得してみましょう。

unread,
Jun 5, 2014, 8:50:12 PM6/5/14
to android-g...@googlegroups.com
最初に提示いただいたソースコードは「Fragment」という仕組みを使用しています。
Fragmentは「パーツとして独立させたActivityのようなもの」で、Activityの中にFragmentを埋め込んで表示させることができます。
※HTMLがわかるのであれば、インラインフレームをイメージすると感覚がつかめると思います。

fragment_test_view_activity2.xmlはFragmentの持つレイアウトで、このレイアウトのViewはActivityのonCreate()の時点では取得することはできません。
そのため、R.id.myTextViewを取得しようとしてもNullになります。

最近はプロジェクトの作成時に「BlankActivity」を選択すると、自動的にFragmentの仕組みを使用したプロジェクトが作製されるようですね。
Fragmentの仕組みをきちんと理解されるのが一番かと思いますが、難しければまずは「EmptyActivity」でプロジェクトを作成すると、テキストのサンプルに近い形になると思います。
※テキストには「 if (savedInstanceState == null) { 」の辺りの4行が無いと推測しています。

Kyash

unread,
Jun 5, 2014, 9:24:00 PM6/5/14
to android-g...@googlegroups.com
Kyashと申します.

onCreateではレイアウトが完成していないので,TextViewなどのレイアウト上のWidgetは取得できないというのは,
いろんな方がおっしゃられている通りです.
fkmさんなどがご提案されている方法は知りませんでしたが,

簡単に取得したければonResume以降のライフサイクル内でfindVieByIdすれば取れると思います.
(もちろんonPauseの後は除きますが...)
タイミング的にonCreateで取得できなければ困る場合には使えませんけど...
(私は,onResumeで取得しても困ったことがありませんので,こうしています)

何かのご参考になれば幸いです.
以上です.


Mika Pucca

unread,
Jun 6, 2014, 7:35:17 AM6/6/14
to android-g...@googlegroups.com
suppi__様

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

cleanをしてみましたが、実行しますと強制終了のエラーが同じように出てしまいました。
やはりソースに原因があるのかもしれません。
ご指摘ありがとうございます。

Shigeo Mutoh

unread,
Jun 6, 2014, 8:27:02 AM6/6/14
to android-g...@googlegroups.com
武藤です。

fragment_test_view_activity2.xmlにid=myTextViewが書いてあるんですよね?

setContentView(R.layout.activity_test_view_activity2);
ではなくて、
setContentView(R.layout.fragment_test_view_activity2.xml);
にすべきだったのではないですか?

では。

Mika Pucca

unread,
Jun 6, 2014, 11:32:01 AM6/6/14
to android-g...@googlegroups.com
fkm様 

再度のご回答ありがとうございます。

お教えいただきました方法で実行してみましたが、同じく強制終了をしてしまいました。
私のやり方が間違っていると思いますので再度、試してみます。

御教示いただきありがとうございます。

Mika Pucca

unread,
Jun 6, 2014, 11:39:43 AM6/6/14
to android-g...@googlegroups.com
楓様

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

ご指摘いただいた通り、テキストには「 if (savedInstanceState == null) { 」の辺りの4行の記載がなかったです。

お教えいただいた「EmptyActivity」でプロジェクトを作成しましたらエディタ上に表示させることに成功しました。

ありがとうございます。大変助かりました。

まだまだ分からないことだらけですので、今後Fragmentの仕組みについても勉強してみます。

本当にありがとうございました。

Mika Pucca

unread,
Jun 6, 2014, 11:52:31 AM6/6/14
to android-g...@googlegroups.com
Kyash様

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

onResumeでfindVieByIdを使ったところ表示させることに成功しました。

大変助かりました。
本当にありがとうございます。

Mika Pucca

unread,
Jun 6, 2014, 12:05:32 PM6/6/14
to android-g...@googlegroups.com
武藤様

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

setContentView(R.layout.fragment_test_view_activity2.xml); と修正し、実行しましたところ同じように強制終了してしまいました。
私のidの設定やソースが間違っているのかと思います。
idの設定や仕組みについて勉強し、見直してみます。

ご指摘いただきありがとうございます。

Stew Eucen

unread,
Jun 7, 2014, 9:10:55 AM6/7/14
to android-g...@googlegroups.com
解決されたようですが、少し将来役立ちそうな話を紹介しておきますね。

onResume() でも目的の挙動は得られますが、このライフサイクルメソッド(=onResume)は「画面がバックグラウンドから復帰したとき」にも実行されます。つまり、アプリ起動後にHOMEボタンを押してバックグラウンドに入った後、再度アプリを立ち上げたときにも実行されるわけです。

TextViewにセットする文字が固定だとすると、アプリが画面に再表示されるたびにセットするのは、ライフサイクル的には無駄な挙動といえます。

「Activity#onCreate()からFragment#onCreate()でセットされたViewのIDを取って、立ち上げ時に一度だけ処理する」のであれば、Activity#onPostCreate() で実行するのが最適だと思います。入門書の類には余り載ってませんが、Fragmentが当たり前の実装になってきているので、重要度が上がってるライフサイクルメソッドだと考えています。

Stew Eucen


2014年6月5日木曜日 20時15分35秒 UTC+9 Mika Pucca:

Mika Pucca

unread,
Jun 7, 2014, 11:34:49 AM6/7/14
to android-g...@googlegroups.com
Stew Eucen様

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

さっそくonPostCreate() で実行したところちゃんと表示されました。

テキストにもアクティビティのライフサイクルについて説明が記載されておりますが、お教えいただいたことまでは記載されておりませんでした。
大変参考になりました。テキストに追加させていただきます。

同じように表示されてもメソッドによって呼び出されるタイミングが違うというところも注意しなければならないということで、まだどのメソッドがどの役割なのかあまり分かっていないので、テキストだけでなくネットでも調べて勉強してみます。

わざわざご丁寧にお教えいただき、ありがとうございます。

Stew Eucen

unread,
Jun 7, 2014, 12:54:55 PM6/7/14
to android-g...@googlegroups.com
Mika Pucca さま

さっそくonPostCreate() で実行したところ
新規の情報を聞いたときに、すぐ試してみるのは素晴らしい。
Puccaさんのアジャイル的な姿勢は、これから出会う数多くのバグにも立ち向かっていけると思います。

ライフサイクルについては他にも役立ちそうなことが山ほどあるのですが、あとひとつだけ「調べ方」を紹介。
入門書類の言う通りに作っていた頃の自分にも教えてやりたいほどです(笑)

(1) ライフサイクル関連のメソッドは、onなんとか。
Activity#onXxxxxx
Fragment#onXxxxx
(2) 上記の全部のメソッドについて全部@Overrideしたメソッドを用意してLogを仕込む
(3) アプリを起動して、ホームボタンでバックグラウンドに入れたり、バックキーで停止させたりして、Logが出る順番を調べる

実際には(3)までの手順では動作しないメソッドがあるのですが、
それを説明するのにOSバージョンとかインテントやタスクなどの概念の説明が必要でして。
そこまで書くとスレッド違いになるので割愛します。

Puccaさんがライフサイクルで再度悩んだときには、役立ちそうな情報を紹介しますね。


Stew Eucen



2014年6月8日日曜日 0時34分49秒 UTC+9 Mika Pucca:

さわださとし

unread,
Jun 7, 2014, 1:17:33 PM6/7/14
to android-g...@googlegroups.com
さわだです。

これこれ!
Androidに限らずよくやります。
ドキュメントを読んでもピンと来ない時は、全部のコールバックに
Overrideでログを仕込んで、いろいろな操作をしながらどのメソッドが
呼ばれるのか試すって、すっごく大切だと思います。

実際にOverrideを書くときには、

@Override
public void onHogeHoge(Type params) {
super.onHogeHoge(params);
Log.d(TAG, "hogehoge");
}

みたいに、スーパークラスのメソッドを呼び出すのが大切です。
そうしないと挙動が変わることがあるので要注意です。

でもログに限った話ならば、その環境でAOP使えるならAOPでログ出力
やってしまう方がはるかに楽ですね。

> ライフサイクルについては他にも役立ちそうなことが山ほどあるのですが、あとひとつだけ「調べ方」を紹介。
> 入門書類の言う通りに作っていた頃の自分にも教えてやりたいほどです(笑)
>
> (1) ライフサイクル関連のメソッドは、onなんとか。
> Activity#onXxxxxx
> Fragment#onXxxxx
> (2) 上記の全部のメソッドについて全部@Overrideしたメソッドを用意してLogを仕込む
> (3) アプリを起動して、ホームボタンでバックグラウンドに入れたり、バックキーで停止させたりして、Logが出る順番を調べる

--
さわださとし
http://www.satoshis.com/

Mika Pucca

unread,
Jun 8, 2014, 6:17:32 AM6/8/14
to android-g...@googlegroups.com
Stew Eucen様

再度のご回答ありがとうございます。

調べ方までお教えいただき感謝感謝です。

実際に試して、実感してみます。

たびたびありがとうございます。

Mika Pucca

unread,
Jun 8, 2014, 6:25:39 AM6/8/14
to android-g...@googlegroups.com
Satoshi Sawada様

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

Overrideのソースまでお教えいただき大変助かります。
さっそく試してみます。

またAOPでログ出力をした方が楽とのことで、まだまだ分からないことだらけですので調べてみます。

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