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

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

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

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

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

Android

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

Android Studio

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

Q&A

0回答

692閲覧

Android Roomでユーザ入力値をViewModelへ渡したいです(NullPointerException)。

Yakusugi

総合スコア123

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

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

Android

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

Android Studio

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

0グッド

0クリップ

投稿2021/12/13 08:09

編集2021/12/16 11:38

家計簿アプリをAndroid Studioで作成しています。

目的は、ShopFragmentで作成したShop画面から店名で、SELECT文を発行する事です。
budgetTrackerViewModel以下の下位階層(SQL文含め)は出来ており、まずはShopFragmentからbudgetTrackerViewModelへユーザ入力値を渡すところまで行いたいです。

DBはAndroid Room(SQLite)を使用しており、下記の通りShopFragment.javaでユーザ入力を受け取り、
受け取った入力文字列を下位階層のBudgetTrackerViewModel.javaへ渡すところまでをまずは行いたいのですが、
下記NullPointerエラーが発生してしまいます。
エラーを読み込むと、ShopFragmentの81行目のbudgetTrackerViewModel.getStoreNameLists(storeName);でViewModelクラスのgetStoreNameListsメソッドの呼び出しでNullPointerExceptionが発生していました。

ShopFragmentでユーザ入力値を受け取り、受け取った値をString storeName = enterStoreNameForQuery.getText().toString();でstoreName に代入し、budgetTrackerViewModel.getStoreNameLists(storeName);でbudgetTrackerViewModelのgetStoreNameListsメソッドを呼び出しているのですが、ここでエラーが発生しており、何故NullPointerExceptionエラーが発生するのか、原因が掴めておりません。

ご助力頂けますと幸いです。

エラー内容

2021-12-16 16:39:45.420 30171-30171/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.myproject.offlinebudgettrackerappproject, PID: 30171 java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.myproject.offlinebudgettrackerappproject.model.BudgetTrackerViewModel.getStoreNameLists(java.lang.String)' on a null object reference at com.myproject.offlinebudgettrackerappproject.ShopFragment$1.onClick(ShopFragment.java:86) at android.view.View.performClick(View.java:7259) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) at android.view.View.performClickInternal(View.java:7236) at android.view.View.access$3600(View.java:801) at android.view.View$PerformClick.run(View.java:27892) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

ShopFragment.java

package com.myproject.offlinebudgettrackerappproject; import android.app.Application; import android.os.Bundle; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import com.myproject.offlinebudgettrackerappproject.model.BudgetTracker; import com.myproject.offlinebudgettrackerappproject.model.BudgetTrackerViewModel; import java.util.List; /** * A simple {@link Fragment} subclass. * Use the {@link ShopFragment#newInstance} factory method to * create an instance of this fragment. */ public class ShopFragment extends Fragment { BudgetTrackerViewModel budgetTrackerViewModel; // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; // TODO: Rename and change types of parameters private String mParam1; private String mParam2; public ShopFragment() { // Required empty public constructor } /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment ShopFragment. */ // TODO: Rename and change types and number of parameters public static ShopFragment newInstance(String param1, String param2) { ShopFragment fragment = new ShopFragment(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_shop, container, false); EditText enterStoreNameForQuery = (EditText) view.findViewById(R.id.shop_search); Button storeSearchQueryBtn = (Button) view.findViewById(R.id.btn_shop_search); storeSearchQueryBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { BudgetTracker budgetTracker; String storeName = enterStoreNameForQuery.getText().toString(); budgetTrackerViewModel = new ViewModelProvider.AndroidViewModelFactory(ShopFragment.this .getApplication()) .create(BudgetTrackerViewModel.class); budgetTracker = new BudgetTracker(); budgetTracker.setStoreName(storeName); budgetTrackerViewModel.getStoreNameLists(storeName); Log.d("TAG", "onClick: " + enterStoreNameForQuery.getText().toString()); // Log.d("TAG", "onClick: " + list); } }); return view; } }

BudgetTrackerViewModel.java

package com.myproject.offlinebudgettrackerappproject.model; import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import com.myproject.offlinebudgettrackerappproject.data.BudgetTrackerRepository; import java.util.List; public class BudgetTrackerViewModel extends AndroidViewModel { public static BudgetTrackerRepository repository; public final LiveData<List<BudgetTracker>> allBudgetTrackerLists; public List<BudgetTracker> storeNameLists; public BudgetTrackerViewModel(@NonNull Application application) { super(application); repository = new BudgetTrackerRepository(application); allBudgetTrackerLists = repository.getAllBudgetTrackerData(); } public LiveData<List<BudgetTracker>> getAllBudgetTrackerLists() { return allBudgetTrackerLists; } public List<BudgetTracker> getStoreNameLists(String storeName) { storeNameLists = repository.queryStoreName(storeName); return storeNameLists; } public static void insert(BudgetTracker budgetTracker) { repository.insert(budgetTracker); } }

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

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

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

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

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

jimbe

2021/12/15 09:52

> budgetTrackerViewModel.getStoreNameLists(storeName); 該当行には null になる可能性のあるオブジェクトが二つ書かれています。 どちらが null になっているかはお分かりになっていますでしょうか。
Yakusugi

2021/12/16 07:49

>どちらが null になっているかはお分かりになっていますでしょうか。 storeNameの方がnullになる可能性があるのでしょうか。 ShopFragmentの82~84行目を下記の様にDTOを通す形で修正してみたのですが、結果はまたNullPointerエラーになってしまいました。 String storeName = enterStoreNameForQuery.getText().toString(); budgetTracker = new BudgetTracker(); budgetTracker.setStoreName(storeName); もし、可能であればもう少しヒントを頂けますと幸いです。
jimbe

2021/12/16 07:52

「二つ」と書きましたが、もう一つは如何でしょうか。
jimbe

2021/12/16 07:56

修正の前に、二つのそれぞれの値が何になっているかをまず確認してください。 該当行の直前で表示する等すれば確認できるはずです。 確認せずに修正するのは、"修正"では無く"無駄"です。
Yakusugi

2021/12/16 08:19

すみません。 先ほどの問題点を検証する前に、書き換えてしまったため、ご質問に回答するのが難しい状況になってしまいました。 大変お手数ではふございますは、現状から問題点を解決する為、ご助力頂けないでしょうか。
jimbe

2021/12/16 11:05

こちらに載せているコードであれば、編集の履歴から以前のコードが見られます。
Yakusugi

2021/12/16 11:42

ありがとうございます。 デバッグモードで実行した所、budgetTrackerViewModelがnullになってましたね。 そこで、ShopFragmentの85~87行目を編集したのですが、 「.getApplication())」の部分でエラーが発生してしまいました。 Fragmentからですと、MainActivityで出来た事が出来ないことが多いように感じます。 ViewModelクラスのインスタンス化が出来ず、詰まってしまいました。 ご助力頂けますと幸いです。 また、2つNullになる可能性があると仰っておりましたが、 storeNameの方は値が入っていたと認識しております。 ※デバッグモードで確認しました。
jimbe

2021/12/16 18:26 編集

ご確認頂いた通り、 該当行では null になる可能性のあったのは budgetTrackerViewModel と storeName です。 そしてこの二つの変数の成り立ちを追ってみれば、 budgetTrackerViewModel に設定している所はありませんでした。従いまして、デバッグモード等使う必要も無く、まず budgetTrackerViewModel は null だろうとほぼ確信できます。 ツールを使えるのは大事ですが、何の為に使うのかを使う側がちゃんと分かっていなければ意味がありません。 作ったプログラムが思い通りに動かないことは、良くあることです。 まずは落ち着いて、最後の状況・表示から何が起きたのかを推測の上、それを確認する為に必要ならツールを使う…というように、順番に進めていった方が良いと思います。 ViewModel の取得方法ですが、本質は Activity と変わりません。 もし ViewModel を Activity に保存するのであれば、当然 Fragment でも Activity から取り出す必要があります。 また、 ViewModel は取り出す際にそもそも保存されていなかったら、システムによって先に作成・保存されます。従いましてアプリで new する必要はありません。 具体的には budgetTrackerViewModel = new ViewModelProvider(requireActivity()).get(budgetTrackerViewModel.class); と言ったコードで取得できます。 ただ、公式的には「fragment の生成時の処理は onViewCreated に書く」という方針のような記事を見た覚えがあります。(非公式? なら [FragmentのonCreateView()とonViewCreated()の使い分け](https://qiita.com/beyondseeker/items/5670e11341fa12f3a0ee ) のような感じです。) 従いまして、現状 onCreateView にあるコードの殆どを onViewCreated に移した上で ViewModel の取得を上記コードのようにされるのが確実に思います。
jimbe

2021/12/16 18:58 編集

BudgetTrackerViewModel は AndroidViewModel では無く ViewModel を継承するようにしてください。 repository = new BudgetTrackerRepository(application); が出来なくなりますが、BudgetTrackerViewModel の setter で repository を貰えば済むと思います。 ViewModel のフィールドは private にし、アクセスは setter/getter で制御されたほうが良いように思います。storeNameLists などは getter があるのに public なのは変です。 また、 static はまず意味が無いか、オブジェクトの設計が間違っているように感じます。 repository フィールドや insert メソッドはインスタンスフィールド・メソッドとして設計されたほうが良いのではないでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問