1

I’m having a problem whereby the program crashes when I click the action_add_event icon button to add a new event in tge EventDetails activity. The EventDetails activity asks for details of the event and the data will be stored into the database and will be transferred back to the MainActivity for displaying.

This is the logcat when the app crashes

2020-11-20 23:31:45.778 1993-1993/? I/.eventcountdow: Not late-enabling -Xcheck:jni (already on)
2020-11-20 23:31:45.847 1993-1993/? E/.eventcountdow: Unknown bits set in runtime_flags: 0x8000
2020-11-20 23:31:45.848 1993-1993/? W/.eventcountdow: Unexpected CPU variant for X86 using defaults: x86
2020-11-20 23:31:46.491 1993-1993/com.example.eventcountdown W/RenderThread: type=1400 audit(0.0:423): avc: denied { write } for name="property_service" dev="tmpfs" ino=6750 scontext=u:r:untrusted_app:s0:c140,c256,c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=0
2020-11-20 23:31:46.496 1993-2019/com.example.eventcountdown D/libEGL: Emulator has host GPU support, qemu.gles is set to 1.
2020-11-20 23:31:46.498 1993-2019/com.example.eventcountdown W/libc: Unable to set property "qemu.gles" to "1": connection failed; errno=13 (Permission denied)
2020-11-20 23:31:46.560 1993-2019/com.example.eventcountdown D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
2020-11-20 23:31:46.562 1993-2019/com.example.eventcountdown D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
2020-11-20 23:31:46.619 1993-2019/com.example.eventcountdown D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
2020-11-20 23:31:47.007 1993-1993/com.example.eventcountdown W/.eventcountdow: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
2020-11-20 23:31:47.008 1993-1993/com.example.eventcountdown W/.eventcountdow: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
2020-11-20 23:31:47.205 1993-2017/com.example.eventcountdown D/HostConnection: HostConnection::get() New Host Connection established 0xd784ffa0, tid 2017
2020-11-20 23:31:47.241 1993-2017/com.example.eventcountdown D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_gles_max_version_3_0 
2020-11-20 23:31:47.245 1993-2017/com.example.eventcountdown W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
2020-11-20 23:31:47.265 1993-2017/com.example.eventcountdown D/eglCodecCommon: setVertexArrayObject: set vao to 0 (0) 0 0
2020-11-20 23:31:47.265 1993-2017/com.example.eventcountdown D/EGL_emulation: eglCreateContext: 0xedc7fdc0: maj 3 min 0 rcv 3
2020-11-20 23:31:47.279 1993-2017/com.example.eventcountdown D/EGL_emulation: eglMakeCurrent: 0xedc7fdc0: ver 3 0 (tinfo 0xe2b4ac40)
2020-11-20 23:31:47.346 1993-2017/com.example.eventcountdown W/Gralloc3: mapper 3.x is not supported
2020-11-20 23:31:47.354 1993-2017/com.example.eventcountdown D/HostConnection: createUnique: call
2020-11-20 23:31:47.355 1993-2017/com.example.eventcountdown D/HostConnection: HostConnection::get() New Host Connection established 0xd7851710, tid 2017
2020-11-20 23:31:47.390 1993-2017/com.example.eventcountdown D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_gles_max_version_3_0 
2020-11-20 23:31:47.391 1993-2017/com.example.eventcountdown D/eglCodecCommon: allocate: Ask for block of size 0x1000
2020-11-20 23:31:47.397 1993-2017/com.example.eventcountdown D/eglCodecCommon: allocate: ioctl allocate returned offset 0x3ffff2000 size 0x2000
2020-11-20 23:31:47.495 1993-2017/com.example.eventcountdown D/EGL_emulation: eglMakeCurrent: 0xedc7fdc0: ver 3 0 (tinfo 0xe2b4ac40)
2020-11-20 23:31:47.501 1993-2017/com.example.eventcountdown D/eglCodecCommon: setVertexArrayObject: set vao to 0 (0) 1 0
2020-11-20 23:31:48.096 1993-2004/com.example.eventcountdown I/.eventcountdow: Background young concurrent copying GC freed 3484(960KB) AllocSpace objects, 1(20KB) LOS objects, 81% free, 1355KB/7499KB, paused 649us total 214.184ms
2020-11-20 23:31:48.331 1993-1993/com.example.eventcountdown I/Choreographer: Skipped 68 frames!  The application may be doing too much work on its main thread.
2020-11-20 23:31:54.032 1993-1993/com.example.eventcountdown W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@e1c1488
2020-11-20 23:31:54.408 1993-1993/com.example.eventcountdown D/AndroidRuntime: Shutting down VM
2020-11-20 23:31:54.415 1993-1993/com.example.eventcountdown E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.eventcountdown, PID: 1993
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.eventcountdown/com.example.eventcountdown.EventDetails}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.example.eventcountdown.eventDbHelper.getWritableDatabase()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        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)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.example.eventcountdown.eventDbHelper.getWritableDatabase()' on a null object reference
        at com.example.eventcountdown.EventDetails.onCreate(EventDetails.java:36)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        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) 
2020-11-20 23:31:54.440 1993-1993/com.example.eventcountdown I/Process: Sending signal. PID: 1993 SIG: 9

MainActivity.java

public class MainActivity extends androidx.appcompat.app.AppCompatActivity {
    private static final String TAG = "MainActivity";
    private eventDbHelper mHelper;
    private ListView mEventListView;
    private ArrayAdapter<String> mAdapter;
    private DatePickerDialog.OnDateSetListener mDateSetListener;
    EditText event;
    TextView date, time;


    public interface DateDialogListener {
        void onFinishDialog(Date date);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHelper = new eventDbHelper(this);
        mEventListView = (ListView) findViewById(R.id.events);


        updateUI();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add_event:
                Intent intent = new Intent(getApplicationContext(), EventDetails.class);
                startActivity(intent);

                String title = getIntent().getStringExtra("EVENT_TITLE");
                String date = getIntent().getStringExtra("EVENT_DATE");
                String time = getIntent().getStringExtra("EVENT_TIME");
                updateUI();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public void deleteEvent(View view) {
        View parent = (View) view.getParent();
        TextView eventTextView = (TextView) parent.findViewById(R.id.event_title);
        String event = String.valueOf(eventTextView.getText());
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.delete(eventContract.EventEntry.TABLE,
                eventContract.EventEntry.COL_EVENT_TITLE + " = ?",
                new String[]{event});
        db.close();
        updateUI();
    }

    private void updateUI() {
        ArrayList<String> eventList = new ArrayList<>();
        SQLiteDatabase db = mHelper.getReadableDatabase();
        Cursor cursor = db.query(eventContract.EventEntry.TABLE,
                new String[]{eventContract.EventEntry._ID, eventContract.EventEntry.COL_EVENT_TITLE},
                null, null, null, null, null);
        while (cursor.moveToNext()) {
            int idx = cursor.getColumnIndex(eventContract.EventEntry.COL_EVENT_TITLE);
            eventList.add(cursor.getString(idx));
        }

        if (mAdapter == null) {
            mAdapter = new ArrayAdapter<>(this,
                    R.layout.new_event,
                    R.id.event_title,
                    eventList);
            mEventListView.setAdapter(mAdapter);
        } else {
            mAdapter.clear();
            mAdapter.addAll(eventList);
            mAdapter.notifyDataSetChanged();
        }

        cursor.close();
        db.close();
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    android:gravity="center_horizontal"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/events"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

EventDetails.java

public class EventDetails extends AppCompatActivity {
    private eventDbHelper mHelper;
    EditText event;
    TextView date, time;
    Button done, cancel;
    //mHelper = new eventDbHelper(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_details);

        event = (EditText) findViewById(R.id.event_title);
        date = (TextView) findViewById(R.id.event_date);
        time = (TextView) findViewById(R.id.event_time);
        done = (Button) findViewById(R.id.Done);
        cancel = (Button) findViewById(R.id.Cancel);

        SQLiteDatabase db = mHelper.getWritableDatabase();
        ContentValues eTitle = new ContentValues();
        ContentValues eDate = new ContentValues();
        ContentValues eTime = new ContentValues();


        done.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String e = String.valueOf(event.getText());
                SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                String d = sdf.format(new Date());
                String t = String.valueOf(time.getText());

                eTitle.put(eventContract.EventEntry.COL_EVENT_TITLE, e);
                eDate.put(eventContract.EventEntry.COL_EVENT_DATE, d);
                eTime.put(eventContract.EventEntry.COL_EVENT_TIME, t);
                db.insertWithOnConflict(eventContract.EventEntry.TABLE,
                        null,
                        eTitle,
                        SQLiteDatabase.CONFLICT_REPLACE);
                Intent intent = new Intent(getBaseContext(), MainActivity.class);
                intent.putExtra("EVENT_TITLE", e);
                intent.putExtra("EVENT_DATE", d);
                intent.putExtra("EVENT_TIME", t);
                startActivity(intent);
            }
        });

        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(EventDetails.this, "Event Cancelled!", Toast.LENGTH_SHORT).show();
                Intent intent  = new Intent(getApplicationContext(), MainActivity.class);
            }
        });
    }
}

activity_event_details.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_gravity="center_vertical"
    android:orientation="vertical"
    android:padding="10dp"
    android:gravity="center_horizontal"
    tools:context=".EventDetails">


    <TextView
        android:id="@+id/pageTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="false"
        android:layout_centerHorizontal="true"
        android:layout_marginStart="130dp"
        android:layout_marginLeft="130dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp"
        android:hint="Enter Event Details"
        android:inputType="text"
        android:textColor="#000000"
        android:textSize="30sp" />

    <EditText
        android:id="@+id/event_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/pageTitle"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="57dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp"
        android:hint="Event Title"
        android:inputType="text"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/event_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/event_title"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="22dp"
        android:layout_marginLeft="22dp"
        android:layout_marginTop="80dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp"
        android:hint="Date"
        android:inputType="text"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/event_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/event_date"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="22dp"
        android:layout_marginLeft="22dp"
        android:layout_marginTop="59dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp"
        android:hint="Time"
        android:inputType="text"
        android:textSize="20sp" />

    <Button
        android:id="@+id/Done"
        android:layout_width="511dp"
        android:layout_height="wrap_content"

        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/event_time"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="5dp"
        android:text="Done" />

    <Button
        android:id="@+id/Cancel"
        android:layout_width="511dp"
        android:layout_height="wrap_content"

        android:layout_alignWithParentIfMissing="true"
        android:layout_below="@+id/Done"

        android:layout_marginTop="30dp"
        android:layout_marginBottom="5dp"
        android:text="Cancel" />

</RelativeLayout>

eventDbHelper.java

public class eventDbHelper extends SQLiteOpenHelper {


    public eventDbHelper(Context context) {
        super(context, eventContract.DB_NAME, null, eventContract.DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase myDB) {
        String createTable = "CREATE TABLE " + eventContract.EventEntry.TABLE + " ( " +
                eventContract.EventEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                eventContract.EventEntry.COL_EVENT_TITLE + " TEXT NOT NULL," +
                eventContract.EventEntry.COL_EVENT_DATE + " TEXT NOT NULL," +
                eventContract.EventEntry.COL_EVENT_TIME  +  " TEXT NOT NULL);";

        myDB.execSQL(createTable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + eventContract.EventEntry.TABLE);
        onCreate(db);
    }
}

eventContract.java

public class eventContract {
    public static final String DB_NAME = "event.db";
    public static final int DB_VERSION = 1;

    public class EventEntry implements BaseColumns {
        public static final String TABLE = "events";

        public static final String COL_EVENT_TITLE = "title";
        public static final String COL_EVENT_DATE = "date";
        public static final String COL_EVENT_TIME = "time";
    }
}

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_add_event"
        android:icon="@android:drawable/ic_menu_add"
        android:title="Add Event"
        app:showAsAction="always" />
</menu>

2 Answers2

2

mHelper is not initialized and therefore the application crashes. You have to initialize it to prevent this from happening.

Try with this in onCreate() method:

eventDbHelper mHelper = new eventDbHelper(this);
2

In java Every instance of a class must call a constructor (instantiation) to become an object. And Android uses java.
That means your activity most specific com.example.eventcountdown.EventDetails must be instantiated internally by the Android System. Which definitely means when you un-comment instantiation at //mHelper = new eventDbHelper(this); note the use of this will probably be unsafe as the internal activity configuration is not done with the instance yet.
Which suggests we should do the same at place we are most sure we are safe. And that is definately in the onCreate method. But which you didn't do. Causing NullPointerException while trying to call from a null object mHelper. Propagating the exception from the OnCreate to form log you see. You need to initialize the

mHelper = new eventDbHelper(this)


inside the onCreate to avoid such an error.

D. Sikilai
  • 467
  • 1
  • 3
  • 17