##環境
PC:Windows10 1607
AndroidStudio:2.2.3
##自身のスキル
普段はLinuxサーバをゴソゴソ弄ってる(一応)インフラサーバエンジニア。クライアント側はほぼからっきし。
IDEを使った開発、およびJava自体が初めてで、入門書読みながら一から勉強しています。
##やろうとしていること
Androidで動くアプリの作成、およびその学習
(最終的にはPCでビルドしたアプリをAndroid端末で動かして、自前のサーバと通信させてあれこれしたい)
##困っていること
設置したボタンを押してonClickでメソッドを実行させようとするとアプリが落ちる。
必ず落ちるわけではなく、IDE上でゴチャゴチャいじるとうまくいく場合もある。
##以下、具体的な症状、手順
AndroidStudioにて、簡単な動作確認アプリを作っています。
本を読みながら一通りボタンやテキストを配置してみて、onClickでメソッドを呼び出し、なんらかの処理をさせて、
Toastで表示させてみる、テキストを書き換えてみるみたいなことは一通りできました(できたんですよ。。)。
参考にした本はこちら
その上で再度自分で一からコーディングしなおしている状況で、以下のような手順でハマっています。。
###作ろうとしているもの
今現在作ろうとしているものは、最もシンプルなものに立ち返り、
-
設置したボタンを押したらonClickで特定のメソッドを呼ぶ
-
呼ばれたメソッドはToastで「Clicked」と表示するだけ
の2点のみです。
###実装手順
- 新規でProjectを生成します。今回再現確認に用いたプロジェクト名は「TestApp9」です。また、Minimum SDKはAPI Level:15、ActivityはEmptyActivityで開始します。
2.デフォルトで置いてあるtextViewはいらないのでDeleteします。
3.activity_main.xml上にWidgetsからButtonを選択し、適当に左上のほうにドロップします。設置されたbuttonのIDは「buttonTest」とし、textにリソースを追加し、追加したリソースのIDを「buttonText」、valueを「test]に設定します。
4.MainActivity.javaを編集し、以下の内容を追記します。
~~~import部分は略~~~
public class MainActivity extends AppCompatActivity {
Button buttonTtest; //追記
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonTtest = (Button) findViewById(R.id.buttonTest); //追記
}
//onClickで動かしたい内容を記述したメソッドを追記
public void onButtonTestClick(View view) {
Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
}
}
最初から書いてあるonCreate以外に追記した部分を新しく書いています。
5.この状態で再度activity_main.xmlに戻り、onClickプロパティに新しく作ったonButtonTestClickを指定します。
選択できるようになっていることを確認しますが、いったん選択せずに(noneのまま)ビルドしてみます。
6.ビルドして、仮想端末上でアプリが起動し、意図通りボタンが配置されていることを確認します。
当然ですが、「TEST」ボタンを押してもなにも反応しません(余談ですが、@string/buttonTestのValueに小文字で値いれたのに大文字になっちゃうの気になりますね。別のボタンとかスタイルにすれば小文字も使えるのかな)。
7.続いて、onClickに先ほど作成したメソッドを指定します。
IDEって便利だけど、裏で何がどう動いてるか(想像はつくけど)わかんないからまだまだ怖い
8.ビルドして実行し、設置したボタンを押してみます。
ちくしょう!台無しにs(以下略
という画面になり、アプリは動作を停止してしまいます。
この時、AndroidStudioのRunカラム(であってますかね?)には、以下のようなJavaの例外がバッと赤字で出力されています。
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not find method onButtonTestClick (MainActivity)(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'buttonTest'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:327)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Application terminated.
IllegalStateException、いやな響きですね。そんななんか怒られるようなことをした覚えはないのですが、とりあえずエラー内容を確認してみます。
java.lang.IllegalStateException: Could not find method onButtonTestClick (MainActivity)(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'buttonTest'
Could not find method と書いてあるので、お前がonClickに指定したメソッド見当たらねぇぞ(゚Д゚)ゴルァ みたいな感じかな?と思います。ただ見当たらないっていっても、IDE的には認識されててドロップダウンリストから選択できたんだけどな。。とちょっともやっともします。
その後もつらつらといっぱい書いてあるのですが、正直よくわかんないです。View.Java:4084 とかあるから、確実に僕が書いた部分でのエラーではなく、エラーが起きた結果後ろでイロイロ問題が起きたのでしょう。大事なのは先頭のエラーだと思っておきます。
あれー、一回はできたのになー、なんでかなーとちょっとゴチャゴチャ弄ってみます。
9.もっかいonClick属性の値を確認してみる。
すると。
なんか2個あるwなんぞこれw
勝手に増えんなww
10.こわいので、いっかいメソッドを亡き者にしてみる。
コメントアウトしてみます。(SublimeTextのマルチカーソルのキモチでCtrl+Altで↓選んだらなんか大量のコードがわわーっと生成されてびびりました。。)
11.onClick属性から消滅したことを確認します。
はい、ちゃんといなくなりましたね。
もっかいビルドすると、当然ですがなんら反応しないボタンがおかれたアプリができます。振り出しに戻りました。
12.再度メソッドを有効化してみる。
さきほどのコメントアウトを解除します。
コメントアウトした際に、自動的にimportからViewとToastが削除されてたみたいです。便利ですね、便利すぎてコワイんですが。赤くなってるところでCtrl+Alt押すと自動でimportしてくれるので、もっかいimportしなおします。
13.メソッドを選択できることを再度確認する。
2個になってたやつが1個にもどってくれましたね。とりあえず一安心といったところでしょうか。
で、今日何度かここらへんごちゃごちゃいじってた時は、こうやって戻してもっかいビルドしなおしたらちゃんと動いた!!ってケースがあったのですが、いまいま確認でもっかいやってたらやっぱりおんなじエラーで動かない。。
14.ほんとにメソッド増やしてみる。
勝手に増えられるのはコワイので、こっちでちゃんと明示的に増やしてみる。onButtonClick2を作りました。
15.選択できることを確認する。
はいそうですね、そういうことです。いいこですね。
せっかくなので新しく作った2でビルドしてみましょう。
16.ちくしょう!台無しにしy(以下略
でもやっぱりビルドして実行してみると同じエラー。。あげくにこんなかんじに。。
だから増えんなwwwwwwバカにしてんのかwwwwww
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not find method onButtonTestClick2 (MainActivity)(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'buttonTest'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:327)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Application terminated.
エラーメッセージもちゃんと2ででます。
###結論
誰もぼくが作ったアプリを愛さない
###ググる
エラーメッセージ近辺でググると、↓ここら辺がヒットします。
stackoverflow(1)
=>タイポじゃね?っていう指摘。今回はAndroidStudioのGUIからメソッド選択してるから、そんなことないと思うんだよね。。
stackoverflow(2)
=>なんかいろいろやってていろいろやったらイケるよ、みたいな雰囲気。今回まったくそんないろいろやってないんだよな・・・
teratail
=>あ、この人といっしょっぽい。なんかすげー辛辣な回答されてる。w
onClick属性の意味を理解していますか?=>まったく理解してないと思います、、きっと、、たぶん。。
stackexchange
=>おおおお、これじゃねこれじゃね?なんか知らんサイトだが、まんまっぽいのを見つけたぞ!!
Update your Gradle to lastest version first and try again. I hope that can be solved your issue by this solution.
えぇー、勝手に入ってきたモンをそれだけ上げるって、こえーな。。やりたくねーな。。
とりあえず。
###再度結論
上記記事にあったワークアラウンドとして、以下の対応で動作させることが可能なことを確認しました。
見事、Toastが表示されました。
onClickで指定したメソッドが『onButtonTestClick (MainActivity)』と書いてあって、後ろの(MainActivity)がイラネ(勝手に入ってくんな!)ってことだったんですかね。。まぁそれでも増殖する意味はわかんないのですが。。
本件に関して、知識をお餅の方がいらっしゃいましたら、ご見解いただけますと幸いです。m(_ _)m