0

I was on my way of making a simple app that retrieves some list data from shared preferences and shows it on the screen. Long story short, the code to display the list is in a fragment 'InventoryFragment'. Inside that, I have a button, and I set an onClick so that an intent is sent to open another activity 'AddActivity'. That's where it crashes, at startActivity(intent).

It is a silly problem, but I can't find the solution. I tried with a simple 'TestActivity' (with just a textview showing up), and that gets shown, but not 'AddActivity'.

What is the error?

InventoryFragment:

package com.coffeetech.kittycatch;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;


public class InventoryFragment extends Fragment {

    public InventoryFragment() {
    }

    //GLOBAL VARIABLES
    private ArrayList<Food> foods;
    private FoodAdapter foodAdapter;
    private ListView listView;
    private FloatingActionButton floatingActionButton;
    private View rootView;
    private Food food; //FOR BUNDLE




    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){

        loadData(); //loading the data into arraylist

        if (getArguments()!=null){
            food.name = getArguments().getString("name");
            food.quantity=getArguments().getInt("quantity");
            food.min_quantity=getArguments().getInt("quantity_min");
            food.type=getArguments().getInt("type");
            foods.add(food);
            saveData();
        }

        //LOCATING THE FRAGMENT LAYOUT
        rootView = inflater.inflate(R.layout.inventory_fragment, container, false);

        //FOOD USAGE
        //foods.add(new Food("Tomatoes", 0, 10, 2));

        //SETTING ADAPTER FOR FOOD LIST
        foodAdapter = new FoodAdapter(getActivity(),foods);

        // SETTING LISTVIEW WITH ADAPTER
        listView = rootView.findViewById(R.id.list_view);
        listView.setAdapter(foodAdapter);

        //setting up the Add button
        floatingActionButton = rootView.findViewById(R.id.add_button);
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Go to ADD activity with no data, since new would be added
                //Intent intent = new Intent(getActivity(),AddActivity.class);
                //startActivity(intent);
                Intent intent = new Intent(getActivity(),AddActivity.class);
                startActivity(intent);
            }
        });

        return rootView;

    }

    private void saveData(){
        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("shared preferences",Context.MODE_PRIVATE );
        Editor editor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(foods);
        editor.putString("inventory",json);
        editor.apply();
    }


    private void loadData(){
        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("shared preferences",Context.MODE_PRIVATE );
        Gson gson = new Gson();
        String json = sharedPreferences.getString("inventory",null);
        Type type = new TypeToken<ArrayList<Food>>(){}.getType();
        foods = gson.fromJson(json,type);

        if (foods==null){
            foods = new ArrayList<Food>();
        }

    }

    @Override
    public void onStop() {
        saveData();
        super.onStop();
    }
}


Layout for the above fragment:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/inventory"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".InventoryFragment">


    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/add_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:layout_margin="52dp"
        android:background="#2196F3"
        android:clickable="true"
        android:src="@android:drawable/ic_menu_add" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp">

    </ListView>

</FrameLayout>

AddActivity:

package com.coffeetech.kittycatch;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class AddActivity extends AppCompatActivity {
    //GLOBAL VARIABLES
    EditText item_name,quantity,quantity_min;
    RadioGroup radio_group;
    String name;
    Button save;
    int q,q_min,type;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_activity);
        item_name = findViewById(R.id.name_add);
        quantity=findViewById(R.id.quantity_add);
        quantity_min=findViewById(R.id.min_quantity_add);
        save=findViewById(R.id.save_button);

        int id = radio_group.getCheckedRadioButtonId();
        if (id == 1000008){
            type=0;
        }else{
            type=1;
        }

        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                name=item_name.getText().toString();
                q=Integer.parseInt(String.valueOf(quantity.getText()));
                q=Integer.parseInt(String.valueOf(quantity.getText()));
                q_min=Integer.parseInt(String.valueOf(quantity_min.getText()));
                //AT THIS POINT, name,q,q_min,type ARE READY TO BE BUNDLED
                InventoryFragment inventoryFragment = new InventoryFragment();
                Bundle args = new Bundle();
                args.putString("name",name);
                args.putInt("quantity_min",q_min);
                args.putInt("quantity",q);
                args.putInt("type",type);
                inventoryFragment.setArguments(args);
                getSupportFragmentManager().beginTransaction().replace(R.id.abcd,inventoryFragment).commit();
            }
        });
    }
}

Layout for above:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/abcd"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="12sp"
    android:layout_marginRight="12sp"
    android:orientation="vertical"
    tools:context=".AddActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Item name: " />

        <EditText
            android:id="@+id/name_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Minimum Quantity: " />

        <EditText
            android:id="@+id/min_quantity_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberDecimal" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Quantity (now): " />

        <EditText
            android:id="@+id/quantity_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="numberDecimal" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Type: " />

        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1">

            <RadioButton
                android:id="@+id/discrete_button_add"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Discrete" />

            <RadioButton
                android:id="@+id/cont_button_add"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Continuous" />
        </RadioGroup>

    </LinearLayout>

    <Button
        android:id="@+id/save_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="SAVE" />

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coffeetech.kittycatch">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".AddActivity" />
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

logcat:

2020-04-05 02:59:54.359 18534-18534/? E/tech.kittycatc: Unknown bits set in runtime_flags: 0x28000
2020-04-05 02:59:54.501 18534-18563/com.coffeetech.kittycatch E/Perf: Fail to get file list com.coffeetech.kittycatch
2020-04-05 02:59:54.502 18534-18563/com.coffeetech.kittycatch E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2020-04-05 02:59:54.502 18534-18563/com.coffeetech.kittycatch E/Perf: Fail to get file list com.coffeetech.kittycatch
2020-04-05 02:59:54.502 18534-18563/com.coffeetech.kittycatch E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2020-04-05 02:59:54.503 18534-18563/com.coffeetech.kittycatch E/Perf: Fail to get file list oat
2020-04-05 02:59:54.504 18534-18563/com.coffeetech.kittycatch E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2020-04-05 03:00:04.424 18534-18534/com.coffeetech.kittycatch E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.coffeetech.kittycatch, PID: 18534
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.coffeetech.kittycatch/com.coffeetech.kittycatch.AddActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.widget.RadioGroup.getCheckedRadioButtonId()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3497)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3636)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2222)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:228)
        at android.app.ActivityThread.main(ActivityThread.java:7782)
        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:981)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.widget.RadioGroup.getCheckedRadioButtonId()' on a null object reference
        at com.coffeetech.kittycatch.AddActivity.onCreate(AddActivity.java:31)
        at android.app.Activity.performCreate(Activity.java:7964)
        at android.app.Activity.performCreate(Activity.java:7953)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3472)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3636) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2222) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:228) 
        at android.app.ActivityThread.main(ActivityThread.java:7782) 
        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:981) 

Thanks in advance to anyone who replies :)

Mike M.
  • 38,532
  • 8
  • 99
  • 95
Sohail Saha
  • 483
  • 7
  • 17
  • 1
    Please [edit] your question to provide the complete [stack trace from the crash](https://stackoverflow.com/a/23353174). – Mike M. Apr 04 '20 at 21:13
  • @MikeM. Duly updated. Sorry, I am new at this. – Sohail Saha Apr 04 '20 at 21:35
  • No worries. Anyhoo, you forgot to do a `findViewById()` for `radio_group` in `AddActivity`, so it's null when you call `getCheckedRadioButtonId()` on it. – Mike M. Apr 04 '20 at 21:36
  • Looks like you'll need to add an `android:id` to the ``, btw. – Mike M. Apr 04 '20 at 21:43
  • @MikeM. Damn! Thanks man! I have a new problem now. The new activity is opening up just fine. But the save functionality isn't working, and it restarts again. Could you take a look into it? – Sohail Saha Apr 04 '20 at 21:46
  • I'm not really sure what you mean. AFAICT, the `save` button in `AddActivity` is loading a new instance of `InventoryFragment`, and passing it the data for a single `Food` object. That `InventoryFragment` instance is only going to have that one new `Food` in its list. It's not going to update the list in the original `InventoryFragment` instance that started `AddActivity`, if that's what you're expecting. – Mike M. Apr 04 '20 at 22:03
  • (Btw, please don't remove information that's relevant to the original question. I'll gladly help you with a few additional pointers here in comments, but if this new issue is not specifically related to the original, it's proper to post a new question for it, if needed. Those new logs don't appear to be coming from your code, anyway.) – Mike M. Apr 04 '20 at 22:04
  • @Mike M. I'm new here, so I didn't know the rule. Alright, I'll post the original logcat tomorrow. – Sohail Saha Apr 04 '20 at 22:22
  • No problem. I already rolled it back, so you don't need to do anything. – Mike M. Apr 04 '20 at 22:22
  • @Mike M. About the explanation that you gave me, yes, I was expecting that, but my code is wrong. What changes do I need to do? In addition to that, that one Food object that I'm passing to the Fragment, even that's not getting added. Can you point me to a solution? – Sohail Saha Apr 04 '20 at 22:23
  • With the given setup, the simplest thing to do would probably be to use `startActivityForResult()` instead, and pass the data back from `AddActivity` to the original `InventoryFragment`. [The examples shown on this post](https://stackoverflow.com/q/920306) mostly show an `Activity` being the original starter, but you would do basically the same thing in your `InventoryFragment`; use `startActivityForResult()`, and override `onActivityResult()`. As for the one item not showing, I'm not sure. The given code looks OK, at first glance, so maybe a problem in the `Adapter`? – Mike M. Apr 04 '20 at 22:32

0 Answers0