質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

2回答

365閲覧

AsyncTaskスレッドからfindViewByIdを呼ぶと例外エラーになります

KumaChan

総合スコア37

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2017/09/01 07:28

AndroidでJSONデータを取得し、それをListViewに表示するプログラムを組もうとしています。

AsyncTaskを使ってJSONデータの取得まではうまくいったのですが、それをメインスレッドのListViewに渡そうとすると「FATAL EXCEPTION」のエラーが出ます。ブレイクポイントで確認したところ、findViewByIdでエラーが出ているようです。

ちょっと長くなりますが、ソースは以下の通りです。

MainActivity.java

package com.example.kuma.testtabasync; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TabHost; import java.util.ArrayList; import static com.example.kuma.testtabasync.R.id.list01; public class MainActivity extends AppCompatActivity { // バックグラウンド用 NetworkTask task; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // バックグラウンドを実行 task = new NetworkTask(this); task.execute("http://nanaco.sub.jp/sample/board.json"); // タブホストを取得 TabHost host = (TabHost) findViewById(R.id.tabHost); host.setup(); // タブ1を定義 TabHost.TabSpec tab01 = host.newTabSpec("tag01"); tab01.setIndicator("掲示板"); tab01.setContent(R.id.tab01); host.addTab(tab01); // タブ2を定義 TabHost.TabSpec tab02 = host.newTabSpec("tag02"); tab02.setIndicator("オフ会"); tab02.setContent(R.id.tab02); host.addTab(tab02); // タブ3を定義 TabHost.TabSpec tab03 = host.newTabSpec("tag03"); tab03.setIndicator("ギャラリー"); tab03.setContent(R.id.tab03); host.addTab(tab03); // アクティブタブ host.setCurrentTab(0); /* // デバッグ用 ArrayList<String> data = new ArrayList<>(); data.add("あああ"); data.add("いいい"); data.add("ううう"); getList(data); */ } // リスト表示 public void getList(ArrayList<String> result){ // System.out.println(result.get(1)); ListView list = (ListView) findViewById(list01); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, result); list.setAdapter(adapter); } }

NetworkTask.java(AsyncTask)

package com.example.kuma.testtabasync; import android.content.Context; import android.os.AsyncTask; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; public class NetworkTask extends AsyncTask<String, Integer, ArrayList> { // メインへアクセス MainActivity main = new MainActivity(); // コンストラクタ public NetworkTask(Context context) { super(); } // 通信用のバックグラウンドメソッド @Override protected ArrayList doInBackground(String... params) { // サイズ可変の変数 StringBuilder data = new StringBuilder(); ArrayList<String> list = new ArrayList<>(); try { // 取得先のURL URL url = new URL(params[0]); // 通信オブジェクトを生成 HttpURLConnection con = (HttpURLConnection)url.openConnection(); // 通信メソッドを指定 con.setRequestMethod("GET"); // 通信オブジェクトからストリーム受信 BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "Shift-JIS")); String line; while ((line = reader.readLine()) != null){ data.append(line); } try { // JSONオブジェクトを生成 JSONArray json = new JSONArray(data.toString()); for (int i = 0; i < json.length(); i++) { JSONObject item = json.getJSONObject(i); JSONObject temp = item.getJSONObject("Board"); String topic = temp.getString("topic"); list.add(topic.toString()); } } catch (JSONException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } return list; } // 通信後の表示用(doInBackgroundの結果がここへ) @Override protected void onPostExecute(ArrayList result) { main.getList(result); } }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabHost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content"> </TabWidget> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/tab01" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/list01" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout> <LinearLayout android:id="@+id/tab02" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/list02" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout> <LinearLayout android:id="@+id/tab03" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/list03" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout> </FrameLayout> </LinearLayout> </TabHost>

MainActivityのgetList(AsyncTaskからの戻り値を表示させるメソッド)で「System.out.println(result.get(n));」とやると表示されるので、おそらくデータは来ているのだと思います。また、その上のコメントアウトしている「デバッグ用」の箇所をコメントインすると、デバッグ用の文字列が表示されます。

ちょっと調べたところ、スレッドをまたいでのUI操作は例外エラーを誘発するとのことで、とはいえどうすればいいのかわからず、困っています。

またまた基本的なところで恐縮ですが、ご教示いただけますと幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

MainActivity.javaでは、NetworkTaskのコンストラクタにMainActivityを渡しているので、そちらを使うと良いでしょう。

public class NetworkTask extends AsyncTask<String, Integer, ArrayList> { // メインへアクセス MainActivity main; // コンストラクタ public NetworkTask(MainActivity context) { super(); main = context; }

投稿2017/09/01 08:05

shimitei

総合スコア799

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KumaChan

2017/09/01 09:09 編集

ご回答、ありがとうございます。そういえば、コンストラクタ経由でMainActivityが渡されてましたね… ということで、以下のように修正してみました。 // メインへアクセス MainActivity main; // コンストラクタ public NetworkTask(MainActivity context) {  super();  main = context; } (中略) @Override protected void onPostExecute(ArrayList result) {  ListView list = (ListView) main.findViewById(list01);  ArrayAdapter<String> adapter = new ArrayAdapter<>(     main, android.R.layout.simple_list_item_1, result);  list.setAdapter(adapter); } 正常に動作しました!!!!! わかりやすいソースのご提示、本当にありがとうございます。 まだまだ知識や理解が足らず、本当に恥ずかしい限りですが、先輩方々のアドバイスをもとにもっともっと勉強してまいりたいと思います。 今後とも、よろしくお願いいたします!!!
guest

0

スレッドがどうかいう問題ではありません。

Activityを継承したクラスはプログラマーがインスタンス化するものではありません。
また、インスタンス化できたとしても、そのインスタンスはAsyncTaskを起動したActivityのインスタンスとは別の物です。

コールバックの仕組みを実装して、AsyncTaskの処理の終了をActivityに通知してするようにしましょう。

投稿2017/09/01 07:35

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KumaChan

2017/09/01 07:41

早々のご回答、ありがとうございます。スレッドの問題じゃないんですね… また、インスタンス化でどうこうできるものではないとのこと、勉強になりました。Androidの基本的な仕組みや作法について理解が十分でないので、もっともっと勉強したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問