Adnan Sheikh
Adnan Sheikh

Reputation: 57

App Stops when using countdown timer

I'm working on an a Quiz App which has five fragments and every fragment has one Question in it. Fragments move in two ways.

  1. When user clicks on an option then the next fragment appears Immediately.
  2. I've a countdown timer that if user does not click on any option then after 10 seconds the fragment is moved to new fragment.

I've implemented the click functions. when user clicks on the option app takes it to the next fragment but if in that next fragment user clicks no option then app stops Immediately. Kindly have a look on this, I'm sharing code.

Question.java (Fragment1)

 package com.example.sheikhspc.testapp;


import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class Question1 extends Fragment implements View.OnClickListener {


public Question1() {
    // Required empty public constructor
}
int counter = 0;
View view;
Fragment frag = null;
TextView tv;
ImageView imageView1, imageViewR, imageView2;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_question1, container, false);
    imageView1 = (ImageView) view.findViewById(R.id.wrong1);
    imageViewR = (ImageView) view.findViewById(R.id.right);
    imageView2 = (ImageView) view.findViewById(R.id.wrong2);
    tv = (TextView) view.findViewById(R.id.timer1);

    imageView1.setOnClickListener(this);
    imageViewR.setOnClickListener(this);
    imageView2.setOnClickListener(this);
    new CountDownTimer(10000, 1000) {

        public void onTick(long millisUntilFinished) {
            tv.setText("Remaining Time: " + millisUntilFinished / 1000);
            //here you can have your logic to set text to edittext
        }

        public void onFinish() {
            frag = new Question2();
            FragmentManager fmm = getFragmentManager();
            FragmentTransaction fragmentTransactionn =  fmm.beginTransaction();
            fragmentTransactionn.addToBackStack(null);

            fragmentTransactionn.replace(R.id.container, frag);

            fragmentTransactionn.commit();

        }


    }.start();


    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.wrong1:
            frag = new Question2();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

            break;
        case R.id.right:
            frag = new Question2();
            FragmentManager fm1 = getFragmentManager();
            FragmentTransaction fragmentTransaction1 = fm1.beginTransaction();

            fragmentTransaction1.replace(R.id.container,frag);

            fragmentTransaction1.commit();





            break;
        case R.id.wrong2:
            frag = new Question2();
            FragmentManager fm2 = getFragmentManager();
            FragmentTransaction fragmentTransaction2 = fm2.beginTransaction();

            fragmentTransaction2.replace(R.id.container,frag);

            fragmentTransaction2.commit();

            break;
        default:
            new CountDownTimer(10000, 1000) {

                public void onTick(long millisUntilFinished) {
                    tv.setText("Remaining Time: " + millisUntilFinished / 1000);
                    //here you can have your logic to set text to edittext
                }

                public void onFinish() {
                    frag = new Question2();
                    FragmentManager fmm = getFragmentManager();
                    FragmentTransaction fragmentTransactionn = fmm.beginTransaction();
                    fragmentTransactionn.addToBackStack(null);

                    fragmentTransactionn.replace(R.id.container, frag);

                    fragmentTransactionn.commit();

                }


            }.start();
            break;

    }
}
}

Question2.java (Fragment2)

package com.example.sheikhspc.testapp;


import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.app.Fragment;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


public class Question2 extends Fragment implements View.OnClickListener {


public Question2() {
    // Required empty public constructor
}


Fragment frag = null;
TextView tv;
View view;
ImageView imageView1, imageViewR, imageView2;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_question2, container, false);

    tv = (TextView)view.findViewById(R.id.timer2);
    imageView1 = (ImageView) view.findViewById(R.id.wrong1);
    imageViewR = (ImageView) view.findViewById(R.id.right);
    imageView2 = (ImageView) view.findViewById(R.id.wrong2);
    imageView1.setOnClickListener(this);
    imageViewR.setOnClickListener(this);
    imageView2.setOnClickListener(this);
    new CountDownTimer(10000, 1000) {

        public void onTick(long millisUntilFinished) {
            tv.setText("seconds remaining: " + millisUntilFinished / 1000);
            //here you can have your logic to set text to edittext
        }

        public void onFinish() {
            tv.setText("done!");
            frag = new Question3();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

        }

    }.start();


    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.wrong1:
            frag = new Question3();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

            break;
        case R.id.right:
            frag = new Question3();
            FragmentManager fm1 = getFragmentManager();
            FragmentTransaction fragmentTransaction1 = fm1.beginTransaction();

            fragmentTransaction1.replace(R.id.container,frag);

            fragmentTransaction1.commit();





            break;
        case R.id.wrong2:
            frag = new Question3();
            FragmentManager fm2 = getFragmentManager();
            FragmentTransaction fragmentTransaction2 = fm2.beginTransaction();

            fragmentTransaction2.replace(R.id.container,frag);

            fragmentTransaction2.commit();

            break;
        default:
            new CountDownTimer(10000, 1000) {

                public void onTick(long millisUntilFinished) {
                    tv.setText("seconds remaining: " + millisUntilFinished / 1000);
                    //here you can have your logic to set text to edittext
                }

                public void onFinish() {
                    tv.setText("done!");
                    frag = new Question3();
                    FragmentManager fm = getFragmentManager();
                    FragmentTransaction fragmentTransaction = fm.beginTransaction();

                    fragmentTransaction.replace(R.id.container,frag);

                    fragmentTransaction.commit();

                }

            }.start();

            break;

    }
}
}

Error Log

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.sheikhspc.testapp, PID: 32330
              java.lang.NullPointerException: Attempt to invoke virtual  method 'android.app.FragmentTransaction  android.app.FragmentManager.beginTransaction()' on a null object reference
                  at com.example.sheikhspc.testapp.Question1$1.onFinish(Question1.java:58)
                  at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5343)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                  at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
I/Process: Sending signal. PID: 32330 SIG: 9
Application terminated.

Second.java (Activity where all the fragments are displayed)

package com.example.sheikhspc.testapp;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.app.Fragment;
import android.os.CountDownTimer;
import android.provider.DocumentsContract;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class Second extends AppCompatActivity {

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

    FragmentManager fm = getFragmentManager();
    FragmentTransaction fragmentTransaction = fm.beginTransaction();

    frag = new Question1();
    fragmentTransaction.replace(R.id.container,frag);

    fragmentTransaction.commit();

}
}

Upvotes: 0

Views: 811

Answers (1)

Multidots Solutions
Multidots Solutions

Reputation: 591

You will need to cancel the timer before you replace the fragment on click.

When you create a new instance of CountDownTimer in onCreate method assign it to a variable for e.g.

CountDownTimer timer = new CountDownTimer(10000, 1000) {...};
timer.start();

And then in onClick method i.e. when user clicks any option stop the timer for e.g.

@Override
public void onClick(View v) {
switch (v.getId()) {
    case R.id.btnNext:

        // Add this line to avoid crash
        timer.cancel();

        frag = new FragmentQuestion2();
        FragmentManager fm = getFragmentManager();
        FragmentTransaction fragmentTransaction = fm.beginTransaction();

        fragmentTransaction.replace(R.id.container,frag);

        fragmentTransaction.commit();

        break;
}

Upvotes: 1

Related Questions