質問するログイン新規登録
Java

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

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

636閲覧

RecyclerView へクエリの実行結果を引数として渡したい

tetejiro

総合スコア17

Java

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

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2023/12/18 11:06

編集2023/12/19 17:43

0

0

実現したいこと

フラグメントの中にRecyclerViewを入れています。
そしてRecyclerViewとしてデータベースからとってきているレコードを
繰り返し表示したいです。

ただ、「←ここが上手くいかない」のところが上手くいきません。
(DailyCalendarFragment.javaの56行目)
ライフサイクルメソッドで、順序を付けているつもりなんですが、
Timely_RecyclerView_Adapterの実行 → クエリの実行
となってしまい、Timely_RecyclerView_Adapterへクエリの実行結果
を渡したいのにクエリがされていないため null で渡されてしまします。
(this.allTimeTable が null になる)

何か解決策ございましたら、ご教授よろしくお願いいたします。

申し訳ありませんが、もし情報が不足しているようでしたら
ご指摘いただけますと幸いです。
どうぞよろしくお願いいたします。

該当のソースコード

DailyCalendarFragment.java

1package com.example.RecordTime; 2 3~省略~ 4 5public class DailyCalendarFragment extends Fragment { 6 7 public static List<TimeTable_RoomEntity> allTimeTable; 8 9 @Override 10 public void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 loadDB(); 13 Log.d("a", "a"); 14 } 15 16 @Override 17 public View onCreateView(LayoutInflater inflater, ViewGroup container, 18 Bundle savedInstanceState) { 19 Log.d("b", "b"); 20 21 // Inflate the layout for this fragment 22 return inflater.inflate(R.layout.daily_calendar_fragment, container, false); 23 } 24 25 26 @Override 27 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 28 Log.d("c", "c"); 29 30 // RecyclerView を生成して各日にちを生成 31 RecyclerView recyclerView = getActivity().findViewById(R.id.time_recycler_view_container); 32 // ①recycleView に layoutManager をセット 33 recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 34 // ②Adapter を生成して RecyclerView にセット 35 recyclerView.setAdapter(new Timely_RecyclerView_Adapter(getContext(), this.allTimeTable)); //←ここが上手くいかない 36 } 37 38 39 public void loadDB() { 40 ExecutorService executor = Executors.newSingleThreadExecutor(); 41 42 executor.submit(new Runnable() { 43 @Override 44 public void run() { 45 Database database = Room.databaseBuilder(getContext(), Database.class, "TimeTable").build(); 46 47 TimeTable_Dao dao = database.timeTable_dao(); 48 dao.insert(new TimeTable_RoomEntity("0番目のtitle")); 49 dao.insert(new TimeTable_RoomEntity("1番目のtitle")); 50 dao.insert(new TimeTable_RoomEntity("2番目のtitle")); 51 52 List<TimeTable_RoomEntity> allTimeTable = dao.getAll(); 53 54 if(allTimeTable.isEmpty()) { 55 Log.d("allTimeTable========>", "empty == true"); 56 } else { 57 Log.d("aaaaaaaaaaaa========>", allTimeTable.get(0).title); 58 } 59 60 DailyCalendarFragment.allTimeTable = allTimeTable; 61 } 62 }); 63 } 64}

Timely_RecyclerView_Adapter.java

1package com.example.RecordTime; 2 3~省略~ 4 5public class Timely_RecyclerView_Adapter extends RecyclerView.Adapter<Timely_RecyclerView_Adapter.ViewHolder> { 6 7 8 // ============= Adapter =============== 9 List<TimeTable_RoomEntity> allTimeTable; 10 Context context; 11 12 Timely_RecyclerView_Adapter(Context context, List<TimeTable_RoomEntity> allTimeTable) { 13 this.context = context; 14 this.allTimeTable = allTimeTable; 15 } 16 17 @Override 18 public int getItemCount() { 19 return 3; 20 } 21 22 @Override 23 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 24// holder.textView.setText(this.allTimeTable.get(position).title); 25 Log.d("e", "e"); 26 } 27 28 @NonNull 29 @Override 30 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 31 View view = LayoutInflater.from(context).inflate(R.layout.time_viewholder, parent, false); 32 Log.d("bbb", "bbb"); 33 return new Timely_RecyclerView_Adapter.ViewHolder(view); 34 } 35 // ============= Adapter =============== 36 37 38 // ============= viewHolder ============ 39 public class ViewHolder extends RecyclerView.ViewHolder { 40 public TextView textView; 41 public ViewHolder(@NonNull View itemView) { 42 super(itemView); 43 this.textView = itemView.findViewById(R.id.time_view_holder); 44 } 45 } 46 // ============= viewHolder ============= 47}

レイアウト追記

①今回メインとして扱うレイアウト

daily_calendar_fragment.xml

1<?xml version="1.0" encoding="utf-8"?> 2<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="300dp" 5 android:layout_height="500dp" 6 android:background="@drawable/border" 7 tools:context=".DailyCalendarFragment"> 8 9 <androidx.recyclerview.widget.RecyclerView 10 android:id="@+id/time_recycler_view_container" 11 android:layout_width="match_parent" 12 android:layout_height="match_parent" /> 13</FrameLayout>

②メインのフラグメント内のRecyclerViewのViewholder

time_viewholder.xml

1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <TextView 7 android:id="@+id/time_view_holder" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:layout_weight="1" 11 android:ems="10" 12 android:text="@string/time_view_holder" /> 13</LinearLayout>

※③今回のメインフラグメントを置くフラグメント

date_fragment.xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent"> 7 8 <LinearLayout 9 android:id="@+id/date" 10 android:layout_width="match_parent" 11 android:layout_height="25sp" 12 android:layout_marginBottom="706dp" 13 android:backgroundTint="@color/design_default_color_primary_dark" 14 android:gravity="center" 15 android:orientation="horizontal" 16 app:layout_constraintBottom_toBottomOf="parent" 17 app:layout_constraintEnd_toEndOf="parent" 18 app:layout_constraintStart_toStartOf="parent" 19 app:layout_constraintTop_toTopOf="parent"> 20 21 <TextView 22 android:id="@+id/selected_month" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:text="@string/fuu" /> 26 27 <TextView 28 android:id="@+id/selected_date" 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:text="@string/selected_date" /> 32 </LinearLayout> 33 34 <androidx.fragment.app.FragmentContainerView 35 android:id="@+id/fragmentContainerView" 36 android:name="com.example.RecordTime.DailyCalendarFragment" 37 android:layout_width="wrap_content" 38 android:layout_height="wrap_content" 39 app:layout_constraintBottom_toBottomOf="parent" 40 app:layout_constraintEnd_toEndOf="parent" 41 app:layout_constraintStart_toStartOf="parent" 42 app:layout_constraintTop_toBottomOf="@+id/date" /> 43 44</androidx.constraintlayout.widget.ConstraintLayout>

★★★引数自体は渡せたかと思いましたがエラーが出るパターン★★★
エラー:No adapter attached; skipping layout

DailyCalendarFragment.java

1package com.example.RecordTime; 2~省略~ 3 4public class DailyCalendarFragment extends Fragment { 5 6 @Override 7 public void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 } 10 11 @Override 12 public View onCreateView(LayoutInflater inflater, ViewGroup container, 13 Bundle savedInstanceState) { 14 View view = inflater.inflate(R.layout.daily_calendar_fragment, container, false); 15 loadDB(view); 16 return view; 17 } 18 19 public void loadDB(View view) { 20 ExecutorService executor = Executors.newSingleThreadExecutor(); 21 22 executor.submit(new Runnable() { 23 @Override 24 public void run() { 25 Database database = Room.databaseBuilder(getContext(), Database.class, "TimeTable").build(); 26 27 TimeTable_Dao dao = database.timeTable_dao(); 28 dao.insert(new TimeTable_RoomEntity("0番目のtitle")); 29 dao.insert(new TimeTable_RoomEntity("1番目のtitle")); 30 dao.insert(new TimeTable_RoomEntity("2番目のtitle")); 31 32 List<TimeTable_RoomEntity> allTimeTable = dao.getAll(); 33 34 setRecyclerView(view, allTimeTable); 35 } 36 }); 37 } 38 39 40 public void setRecyclerView(View view, List<TimeTable_RoomEntity> allTimeTable) { 41 // RecyclerView を生成して各時間を生成 42 RecyclerView recyclerView = view.findViewById(R.id.time_recycler_view_container); 43 // ①recycleView に layoutManager をセット 44 recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 45 // ②Adapter を生成して RecyclerView にセット 46 recyclerView.setAdapter(new Timely_RecyclerView_Adapter(getContext(), allTimeTable)); 47 } 48}

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

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

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

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

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

hoshi-takanori

2023/12/18 11:56

DB アクセスは別スレッドで実行されてるので、その結果が得られたら表示を更新する必要があるかと。 また、定数ではない static 変数を使うのはお勧めしません。
jimbe

2023/12/18 18:21 編集

どこに『「←ここが上手くいかない」』があるのか探してしまいました。ファイル名と行番号を書いて頂ければ探す必要が無くて良いと思います。 それと、フラグメントとしてレイアウトも設定しているのに RecyclerView recyclerView = getActivity().findViewById(R.id.time_recycler_view_container); というのはどういうことでしょう。
tetejiro

2023/12/19 17:44

お二方ともコメント、回答をいただき大変ありがとうございます。 修正をさせていただきました。 また、回答をいただく前に自分で試行錯誤していたので、そちらもせっかくなので 追記をさせていただきました。(★★★引数自体は渡せたかと思いましたがエラーが出るパターン★★★の部分) ※エラー(No adapter attached; skipping layout)が出ており失敗しています。 いただきました回答は、今拝見せさていただいておりますが まだ理解するのに時間をいただきたいと思います。 見終わり次第アクションさせていただきます。 よろしくお願いいたします。
jimbe

2023/12/19 18:53

ここは質問へのコメントですので、回答へのコメントは各回答にある「コメント」にお書きください。 追加されたコードの "No adapter attached; skipping layout" は、 onCreateView 後に RecyclerView を表示しようとした段階でアダプタが設定されていないからです。 それを防ぐ為、私の回答では空のアダプタを設定しておき、 loadDB のデータを後から設定しています。
guest

回答1

0

ベストアンサー

アダプタにデータをセットするメソッドを作り、 loadDB でデータが揃ったら Handler 経由でそのメソッドを呼び出します。

なお、この構造は若干簡易版です。極稀な落ちるタイミングがあります。
もっとちゃんとするなら ViewModel で LiveData を利用することになるでしょう。

(行レイアウトは手抜きのため android の一行レイアウトを使っています)

DailyCalendarFragment.java

java

1import android.annotation.SuppressLint; 2import android.os.*; 3 4import androidx.annotation.NonNull; 5import androidx.annotation.Nullable; 6import androidx.fragment.app.Fragment; 7import androidx.recyclerview.widget.RecyclerView; 8 9import android.util.Log; 10import android.view.*; 11import android.widget.TextView; 12 13import java.util.*; 14import java.util.concurrent.ExecutorService; 15import java.util.concurrent.Executors; 16 17public class DailyCalendarFragment extends Fragment { 18 private static final String LOG_TAG = "DailyCalendarFragment"; 19 20 private final ExecutorService executor = Executors.newSingleThreadExecutor(); 21 private Handler handler; 22 private Adapter adapter; 23 24 DailyCalendarFragment() { 25 super(R.layout.fragment_daily_calendar); 26 } 27 28 @Override 29 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 30 adapter = new Adapter(); 31 32 RecyclerView recyclerView = view.findViewById(R.id.recycler_view); 33 recyclerView.setAdapter(adapter); 34 35 handler = new Handler(Looper.getMainLooper()); 36 37 loadDB(); 38 } 39 40 private void loadDB() { 41 executor.submit(() -> { 42 Log.d(LOG_TAG, "loadDB start."); 43 try { 44 Thread.sleep(3*1000L); //時間が掛かる処理のつもり(分かり易いよう長め) 45 } catch(InterruptedException ignore) { 46 //no process 47 } 48 List<Item> itemList = new ArrayList<>(); 49 itemList.add(new Item("0番目のtitle")); 50 itemList.add(new Item("1番目のtitle")); 51 itemList.add(new Item("2番目のtitle")); 52 53 handler.post(() -> adapter.set(itemList)); 54 Log.d(LOG_TAG, "loadDB end."); 55 }); 56 } 57 58 private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { 59 private final List<Item> itemList = new ArrayList<>(); 60 61 @SuppressLint("NotifyDataSetChanged") 62 void set(List<Item> newItemList) { 63 Log.d(LOG_TAG, "Adapter#set start. newItemList.size()=" + newItemList.size()); 64 itemList.clear(); 65 itemList.addAll(newItemList); //防御コピー 66 notifyDataSetChanged(); 67 Log.d(LOG_TAG, "Adapter#set end."); 68 } 69 70 @Override 71 public int getItemCount() { 72 return itemList.size(); 73 } 74 75 @Override 76 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 77 holder.bind(itemList.get(position)); 78 } 79 80 @NonNull 81 @Override 82 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 83 return new ViewHolder(parent); 84 } 85 86 static class ViewHolder extends RecyclerView.ViewHolder { 87 private final TextView textView; 88 89 private ViewHolder(@NonNull ViewGroup parent) { 90 super(LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false)); 91 textView = itemView.findViewById(android.R.id.text1); 92 } 93 94 private void bind(Item item) { 95 textView.setText(item.title); 96 } 97 } 98 } 99} 100 101class Item { 102 final String title; 103 Item(String title) { 104 this.title = title; 105 } 106}

res/layout/fragment_daily_calendar.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@+id/recycler_view" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

実行結果
エミュレータスクリーンショット
実行時 Logcat

2023-12-19 03:55:44.953 23160-23185 DailyCalendarFragment com.teratail.q_nq6yuripcws7qn D loadDB start. 2023-12-19 03:55:47.955 23160-23160 DailyCalendarFragment com.teratail.q_nq6yuripcws7qn D Adapter#set start. newItemList.size()=3 2023-12-19 03:55:47.955 23160-23160 DailyCalendarFragment com.teratail.q_nq6yuripcws7qn D Adapter#set end. 2023-12-19 03:55:47.955 23160-23185 DailyCalendarFragment com.teratail.q_nq6yuripcws7qn D loadDB end.

投稿2023/12/18 19:06

編集2023/12/19 17:48
jimbe

総合スコア13357

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

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

tetejiro

2023/12/25 06:40 編集

ご回答いただきありがとうございました。 理解に時間がかかり返信が遅くなってしまい、大変申し訳ございませんでした。 質問を重ねてしまい大変恐縮ですが、 以下を確認したく、ご回答をお願いできますでしょうか? ①"No adapter attached; skipping layout" は、 onCreateView 後に RecyclerView を表示しようとした段階でアダプタが設定されていないからです。 それを防ぐ為、私の回答では空のアダプタを設定しておき、 loadDB のデータを後から設定しています。 この言葉が長い間理解できずにいたのですが、以下のような意味で合っていますでしょうか? RecyclerViewで表示するデータの中身を空にしておかないと、 "No adapter attached; skipping layout"エラーが発生する。 そのためRecyclerViewで表示するデータは最初は空にしておき、 その後RecyclerViewクラスのsetメソッドを用いて、表示を更新するという処理にした。 (https://www.jianshu.com/p/da2fda474624 中国語?の記事でした、すみません。この記事と同じことをご指摘いただいていると考えました) ②Thread.sleep(3*1000L); に関してですが、この処理は通常行う、いわゆるベストプラクティスなのでしょうか? 今回扱うデータは小さいデータを想定しているのですが その場合も必要なのでしょうか? ③handler.post(() -> adapter.set(itemList)); に関してですが、handler.post では、キューに積むのと実行を両方する処理ということで合っていますでしょうか? (スレッドを初めて扱うため初歩的な質問ですみません。) ④itemList.addAll(newItemList); //防御コピー に関してですが、以下のサイトの内容のことということで合っていますでしょうか? (受け取る側で new して改ざん不可にすると認識しています。) ※https://thekingsmuseum.info/entry/2016/06/02/231750 たくさん質問をしてしまい大変申し訳ございません。 もしよろしければご回答をよろしくお願いいたします。
jimbe

2023/12/25 07:30 編集

>RecyclerViewで表示するデータの中身を空にしておかないと、 >"No adapter attached; skipping layout"エラーが発生する。 "データの中身" という抽象的(?) な話では無く、単に ”RecyclerView が表示される段階でまだ setAdapter が呼ばれてないから、何をどう表示するのか全く分からないから表示出来ないよ” ということです。 リンク先の内容も(google翻訳が中国語での表現をうまく翻訳出来ているのか分かりませんが)そういうことでしょう。 loadDB で sleep しているのはコメントに書いている通り、 データベースアクセス(は時に時間が掛かるモノなのでそれ)をシミュレートしているだけです。 Android で データベースにアクセスするのを(EDTとは)別スレッドにするというのは、本件のアプリの場合はともかくとして大量のデータがある場合は時間が掛かるものであり、その間アプリが反応しなくなるのを防ぐためです。(本件のコードもその意図を汲んで executor でやっているのではないですか? ) そして Android のライフサイクルのメソッドが呼ばれるよりも時間が掛かっているからこそ本件の問題が発生しています。 逆に言うと、もしデータベースのデータが少なくてライフサイクルのメソッドが呼ばれるよりも時間が掛からず(見た目)正常に動作してしまうと、データが増えて時間が掛かるようになった時に表示がされなくなって何が悪いのか分かり難くなるという面倒なバグになります。 そのため、データベースの読み込みに時間が掛かっても表示がされるということを確認する意味で、データベースに大量のデータを入れるよりも簡単に sleep させています。 回答はあくまで動作確認のサンプルであり、実際のアプリでは当然 sleep は入れません。 >handler.post では、キューに積むのと実行を両方する処理 Android は EDT と呼ばれる単一スレッドが全体の動作を支配しています。EDT の動作自体は簡単で『キューからイベントを取り出して実行』を繰り返すだけです。(つまり Android 自体の中核はシングルスレッドです。) Looper.getMainLooper() から作った Handler はその EDT のキューに対して処理することが出来、 post はキューへの追加です。 キューは常に多くのプログラムからイベントが入れられており EDT は常にそれらを取り出しては実行していますので、やがて post したイベントが EDT に取り出されれば、その時に実行されます。 "防御コピー"とコメントしている個所の意図は、まさにリンク先のことを意識しています。 ビアソンエデュケーションの『Effective Java』は(もう古い初版と第2版ですが)私も持っています。
tetejiro

2023/12/25 09:01

ご丁寧にご回答をしていただき誠にありがとうございます。 質問への対応プラスアルファでこのようにお付き合いいただき 大変感謝しております。 追記もありがとうございました。 質問の内容を、①以外は理解できたと思います。 しつこく聞いてしまってすみませんが もしよろしければ①について教えてくださいますでしょうか? 本当に何度もすみません。 (もし別で質問を立てたほうがよろしければそのようにさせていただきますので、おっしゃってください。) >”RecyclerView が表示される段階でまだ setAdapter が呼ばれてないから、何をどう表示するのか全く分からないから表示出来ないよ” ということです。 onCreateView()でそのフラグメントの View が生成されるので、 それまでに setAdapter をしておけば問題ないのかと思い、 onAttach や onCreate などで事前に setAdapter の処理をしてみましたが それではできませんでした。 このことで、頭が混乱してしまっている状況です。 また、このエラー(No adapter attached; skipping layout)が発生するタイミングをログで出力してみたのですが ※★★★引数自体は渡せたかと思いましたがエラーが出るパターン★★★での実行です。 public void run() { Log.d("ccccccccccc=======>", "cccccccccccc"); <=======C Database database = Room.databaseBuilder(getContext(), Database.class, "TimeTable").build(); TimeTable_Dao dao = database.timeTable_dao(); dao.insert(new TimeTable_RoomEntity("0番目のtitle")); dao.insert(new TimeTable_RoomEntity("1番目のtitle")); dao.insert(new TimeTable_RoomEntity("2番目のtitle")); List<TimeTable_RoomEntity> allTimeTable = dao.getAll(); Log.d("ddddddddddd=======>", "ddddddddd"); <=======D setRecyclerView(view, allTimeTable); Log.d("eeeeeeeee=======>", "eeeeeeeeee"); <=======E } の、 c と d の間で No adapter attached; skipping layout が出ていました。 d と e の間で行われないということで、 私が漏らしている観点のようなものがあるのでしょうか? 大変恐縮ですが、 もしよろしければご回答よろしくお願いします。
jimbe

2023/12/25 11:00 編集

私の回答に関するものであればこちらに書いて頂くのが妥当と思いますし、ご理解頂けなければ回答の意味がありませんので質問頂くのも問題ありません。 >それまでに setAdapter をしておけば 該当の例外は EDT 上で発生しているものですので、別のスレッドの(ログの出力との)タイミングは関係ありません。 EDT は onViewCreated が終わり次第 view を表示しようとします。 onViewCreated の最後の loadDB は「データベースから読み込んで setAdapter を実行するスレッド」(長いので以降 DBRT と呼びます)を起動します。つまり loadDB は即戻ってくるので onViewCreated も早々に終わり、 EDT が view を表示しようとするのと DBRT は同時に実行されていて、しかもどのスレッドが何時何をしているかは別のスレッドは分かりません。マルチスレッドでは(意図して同期処理を書かない限り)あるスレッドのある段階で他のスレッドが何かをし終わっている等は保証されません。 起きている現象は、** たまたま ** DBRT の C と D のログの間くらいの時間に EDT が(レイアウトに定義されている) RecyclerView を表示しようとしており、『あれ? Adapter が無いじゃん』と気が付いて No adapter~ と言っているのです。
tetejiro

2023/12/26 09:37

>loadDB は即戻ってくる ここが理解ができずにいました。 ようやく理解ができたと思います。 本当にありがとうございました。 最初から最後まで本当にご丁寧に回答をしていただき 大変感謝しております。 質問への回答だけでなく、他の学びも大いにあり 勉強になりました。 改めて、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問