new to java and was following a tutorial on building a chronometer app from scratch. The app compiles but when pressing start or stop in emulator the app crashes. Start crashes app without notification, Pause crashes app with notification about crash and fill a report suggestion, stop doesnt crash but does nothing. I have searched multiply sites about it and dont seem to find a problem in it.
main activity java
package com.example.dayswithout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Chronometer;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Chronometer chronometer;
private long pauseOffset;
private Boolean running;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer=findViewById(R.id.chronometer);
chronometer.setFormat("Time: %s");
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
if ((SystemClock.elapsedRealtime() - chronometer.getBase()) >= 10000) {
chronometer.setBase(SystemClock.elapsedRealtime());
Toast.makeText(MainActivity.this, "Bing!", Toast.LENGTH_SHORT).show();
}
}
});
}
public void startChronometer(View v){
if(!running) {
chronometer.setBase(SystemClock.elapsedRealtime()-pauseOffset);
chronometer.start();
running = true;
}
}
public void pauseChronometer(View v){
if(running) {
chronometer.stop();
pauseOffset=SystemClock.elapsedRealtime()-chronometer.getBase();
running = false;
}
}
public void resetChronometer(View v){
chronometer.setBase(SystemClock.elapsedRealtime());
pauseOffset=0;
}
}
activity main xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Chronometer
android:id="@+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startChronometer"
android:text="Start"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause"
android:onClick="pauseChronometer"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="reset"
android:onClick="resetChronometer"/>
</LinearLayout>
Log
02/22 14:19:49: Launching 'app' on No Devices.
Install successfully finished in 1 s 718 ms.
$ adb shell am start -n "com.example.dayswithout/com.example.dayswithout.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 6915 on device 'emulator-5554'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/ple.dayswithou: Not late-enabling -Xcheck:jni (already on)
I/ple.dayswithou: Unquickening 12 vdex files!
W/ple.dayswithou: Unexpected CPU variant for X86 using defaults: x86
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
W/ple.dayswithou: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/ple.dayswithou: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
D/HostConnection: HostConnection::get() New Host Connection established 0xebb41ac0, tid 7013
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_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_async_frame_commands ANDROID_EMU_gles_max_version_2
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/EGL_emulation: eglCreateContext: 0xebb41a50: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xebb41a50: ver 2 0 (tinfo 0xebe96950) (first time)
I/Gralloc4: mapper 4.x is not supported
D/HostConnection: createUnique: call
HostConnection::get() New Host Connection established 0xebb41eb0, tid 7013
D/goldfish-address-space: allocate: Ask for block of size 0x100
allocate: ioctl allocate returned offset 0x3fbda9000 size 0x2000
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_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_async_frame_commands ANDROID_EMU_gles_max_version_2
I/OpenGLRenderer: Davey! duration=1037ms; Flags=1, IntendedVsync=748790555628, Vsync=748807222294, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=748815462000, AnimationStart=748815491400, PerformTraversalsStart=748816913000, DrawStart=749730608800, SyncQueued=749763725800, SyncStart=749765306700, IssueDrawCommandsStart=749765382800, SwapBuffers=749827691200, FrameCompleted=749829712000, DequeueBufferDuration=138600, QueueBufferDuration=791000, GpuCompleted=-2920196950870201425,
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dayswithout, PID: 6915
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
at com.example.dayswithout.MainActivity.startChronometer(MainActivity.java:35)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process: Sending signal. PID: 6915 SIG: 9
Here you have the problem:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
at com.example.dayswithout.MainActivity.startChronometer(MainActivity.java:35)
Which refers to that the running
variable is not initialised:
public void startChronometer(View v){
if(!running) {
I would recommend changing it from a wrapped Boolean
that is an object and not set, so value of it is null
. to a primitive boolean
in the declaration:
private Boolean running;
->
private boolean running = false;
And maybe set it to false for clairity (optional because false is the default value).