Question

I am having an issue with a Fragment and an AsyncTask. The issue is that I am creating a Fragment to run an AsyncTask to run a timer. The code works independently of all my other code and I have tested it numerous times. The issue is that when I place my new code into my app, I get a null pointer at this point:

        public void onClick(View v) {
     if(v==abbtn){
        aboutFragDialog();
    }else if(v==exbtn){
        finish();
    }else if(v==starest){
        if(mTaskFragment.isRunning()){
            mTaskFragment.cancel();
    } else {

            mTaskFragment.start();
    }if(v==mgextbtn){
        mgcusd.dismiss();
     }
    }
}

the actual line that is pushing the error is: if(mTaskFragment.isRunning()){. This code links to the following:

       public void replaceFrag(){
    Bundle bundle = new Bundle();
    String tester2 = String.valueOf(startTime).toString();
    Log.i("VertygoEclypse - replaceFrag - Value for counter ", tester2);
    if(tester2.matches("")){
        bundle.putString("SecValue", "15");
    } else {
        bundle.putString("SecValue", tester2);
    }
    FragmentManager rfm = getSupportFragmentManager();
    if(mTaskFragment == null){
    TaskFragment mTaskFragment = new TaskFragment();
    mTaskFragment.setArguments(bundle);
    rfm.beginTransaction().add(mTaskFragment, "task").commit();
    } else {
        TaskFragment mTaskFragment = new TaskFragment();
        mTaskFragment = (TaskFragment) rfm.findFragmentByTag("task");
        mTaskFragment.setArguments(bundle);
        rfm.beginTransaction().add(mTaskFragment, "task").commit();
    }
}

which gets called from the following:

        @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
    switch(parent.getId()){
        case R.id.timerspinner:
            TimerDataBaseHandler isdb = new TimerDataBaseHandler(getApplicationContext());
            SQLiteDatabase dbsec = isdb.getReadableDatabase();
            int tagposition = s.getSelectedItemPosition()+1;
            isdb.getReadableDatabase();
            Cursor cc = dbsec.rawQuery("SELECT * FROM timers WHERE _id = "+tagposition, null);
            if(cc.moveToFirst()){
                setTimer(Integer.parseInt(cc.getString(2)));
                starest.setEnabled(true);
                replaceFrag();
            }
    }
}

the above code is enough that in my TaskFragment Activity with Logs I can see that the variable I send across is being seen to be used as a startTime for a count down which is here:

        @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    bundle=getArguments();
    i = bundle.getString("SecValue");
    Log.i("VertygoEclypse - TaskFragment-onCreate", i);
    counter=Integer.parseInt(i);
    Log.i("VertygoEclypse - TaskFragment - onCreate", String.valueOf(counter).toString());
}

that being said, this code works as a stand alone and works and gives the expected results. The issue is when I wire it up to work with my app, it seems that although the value moves across to the Fragment I cannot start the Asynctask. Below is my code so far.

This is the TaskFragment.class package com.vertygoeclypse.multitimer;

    import android.app.Activity;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.SystemClock;
    import android.support.v4.app.Fragment;
    import android.util.Log;

    public class TaskFragment extends Fragment {
private static final String TAG = TaskFragment.class.getSimpleName();
String i;
static int counter, validcounter;
Bundle bundle;
static interface TaskCallbacks {
    public void onPreExecute();
    public void onProgressUpdate(int timer);
    public void onCancelled();
    public void onPostExecute();
}
private TaskCallbacks mCallbacks;
private DummyTask mTask;
private boolean mRunning;
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (!(activity instanceof TaskCallbacks)) {
        throw new IllegalStateException("Activity must implement the TaskCallbacks interface.");
    }
    mCallbacks = (TaskCallbacks) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    bundle=getArguments();
    i = bundle.getString("SecValue");
    Log.i("VertygoEclypse - TaskFragment-onCreate", i);
    counter=Integer.parseInt(i);
    Log.i("VertygoEclypse - TaskFragment - onCreate", String.valueOf(counter).toString());
}
@Override
public void onDestroy() {
    super.onDestroy();
    cancel();
}
public void start() {
    if (!mRunning) {
        Log.i("VertygoEclypse - TaskFragment - start", String.valueOf(counter).toString());
        mTask = new DummyTask();
        validcounter = counter;
        Log.i("VertygoEclypse - TaskFragment - validcounter", String.valueOf(validcounter).toString());
        mTask.execute();
        mRunning = true;
    } else{
        mTask.cancel(true);
    }
}
public void cancel() {
    if (mRunning) {
        mTask.cancel(true);
        mTask = null;
        mRunning = false;
    }
}
public boolean isRunning() {
    return mRunning;
}
private class DummyTask extends AsyncTask<Void, Integer, Void> {
    @Override
    protected void onPreExecute() {
        mCallbacks.onPreExecute();
        mRunning = true;

        Log.i("Vertygo Eclypse - AsyncTask - onPreExecute", i);
    }
    @Override
    protected Void doInBackground(Void... ignore) {

        Log.i("Vertygo Eclypse - AsyncTask - onPreExecute", String.valueOf(validcounter).toString());
        do {
            publishProgress(validcounter);
            SystemClock.sleep(1000);
            validcounter=validcounter-1;
            if(isCancelled()){
                mTask.cancel(true);
                break;
            }
        } while (validcounter>0);
        return null;
    }
    @Override
    protected void onProgressUpdate(Integer... timer) {
        mCallbacks.onProgressUpdate(timer[0]);
    }
    @Override
    protected void onCancelled() {
        mCallbacks.onCancelled();
        mRunning = false;
    }
    @Override
    protected void onPostExecute(Void ignore) {
        mCallbacks.onPostExecute();
        mRunning = false;
    }
}
    }

the MainActivity is kinda long so I hope no one gets upset, but I think without seeing the code, a proper assessment can not be made.

    package com.vertygoeclypse.multitimer;
    //--------------------------------------------------------------------------------------------------

    import android.app.Dialog;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.graphics.Typeface;
    import android.os.Bundle;
    import android.os.CountDownTimer;
    import android.os.Handler;
    import android.os.Vibrator;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentManager;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.NumberPicker;
    import android.widget.Spinner;
    import android.widget.TextView;

    import com.vertygoeclypse.multitimer.AddDialog.onSubmitListener;
    import com.vertygoeclypse.multitimer.UpdateDialog.onSubmitUpdateListener;

    import java.io.File;
    import java.util.List;
    import java.util.concurrent.TimeUnit;

    import static android.widget.AdapterView.OnItemSelectedListener;
    //--------------------------------------------------------------------------------------------------
    public class MainActivity extends FragmentActivity implements NumberPicker.OnValueChangeListener, OnClickListener, OnItemSelectedListener, onSubmitListener, onSubmitUpdateListener, TaskFragment.TaskCallbacks {
    //--------------------------------------------------------------------------------------------------
Button  abbtn, exbtn, starest, mgextbtn;
TextView timeRemaining;
Dialog  mgcusd;
Typeface tf;
Spinner s;
Vibrator v;
protected CountDownTimer timerCountDownTimer;
Handler timerHandler = new Handler();
public boolean timerHasStarted = false;
protected int startTime=0;
protected int val1, val2, val3, val4, temp1, upposval, validcounter;
protected String tagval1, temp2, uptagval, uptimeval;
boolean savechkbx=true;
File mydb ;
public static Context PACKAGE_NAME;
private static final String TIME_COUNT = "time_count";
private TaskFragment mTaskFragment;
    //--------------------------------------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //--------------------------------------------------------------------------------------------------
    PACKAGE_NAME = getApplicationContext();
    TimerDataBaseHandler db = new TimerDataBaseHandler(getApplicationContext());
    mydb = new File("/data/data/com.vertygoeclypse.multitimer/databases/TimerManager");
    if(mydb.exists()){

    } else {
        db.addTimer(new TimerClass("Lipton", "180"));
    }
    //--------------------------------------------------------------------------------------------------
    abbtn = (Button) findViewById(R.id.aboutbtn);
    exbtn = (Button) findViewById(R.id.exitbtn);
    starest =  (Button) findViewById(R.id.startresetbtn);
    timeRemaining = (TextView) findViewById(R.id.timeremainingview);
    s = (Spinner)findViewById(R.id.timerspinner);
    tf = Typeface.createFromAsset(getAssets(),"digital7.ttf");
    v  = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    //--------------------------------------------------------------------------------------------------
    abbtn.setOnClickListener(this);
    exbtn.setOnClickListener(this);
    starest.setOnClickListener(this);
    s.setOnItemSelectedListener(this);
    //--------------------------------------------------------------------------------------------------
    if(startTime==0){
        starest.setEnabled(false);
    }else if(startTime>0){
        starest.setEnabled(true);
        starest.setTextColor(getResources().getColor(android.R.color.primary_text_light));
    }
    LoadSpinnerData();

    if (savedInstanceState != null) {
        timeRemaining.setTypeface(tf);
        timeRemaining.setText(savedInstanceState.getString(TIME_COUNT));
    }
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(TIME_COUNT, timeRemaining.getText().toString());
}
    //--------------------------------------------------------------------------------------------------
public void LoadSpinnerData(){
    TimerDataBaseHandler tdb = new TimerDataBaseHandler(getApplicationContext());
    List<String> timerlabels = tdb.fetchAllTimers();
    ArrayAdapter<String> dataAdapter;
    dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, timerlabels);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    s.setAdapter(dataAdapter);
}
public void mgLoadSpinnerData(){
    TimerDataBaseHandler updb = new TimerDataBaseHandler(getApplicationContext());
    List<String> updatetimers = updb.fetchAllTimers();
    ArrayAdapter<String> dataAdapter;
    dataAdapter = new ArrayAdapter<String>(this, R.layout.customer_colored_spinner_item, updatetimers);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    UpdateDialog.mgs.setAdapter(dataAdapter);
}
    //--------------------------------------------------------------------------------------------------
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {}
    //--------------------------------------------------------------------------------------------------
public static String getDurationBreakdown(long secondstobreak) {
    if(secondstobreak < 0)
    {
        throw new IllegalArgumentException("Duration must be greater than zero!");
    }
    long hours = TimeUnit.MILLISECONDS.toHours(secondstobreak);
    secondstobreak-=TimeUnit.HOURS.toMillis(hours);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(secondstobreak);
    secondstobreak-=TimeUnit.MINUTES.toMillis(minutes);
    long seconds = TimeUnit.MILLISECONDS.toSeconds(secondstobreak);
    secondstobreak-=TimeUnit.SECONDS.toMillis(seconds);
    StringBuilder sb = new StringBuilder(64);
    if(hours<10){
        sb.append("0"+hours);
    }else {
    sb.append(hours);
    }
    sb.append(" : ");
    if(minutes<10){
        sb.append("0"+minutes);
    }else{
    sb.append(minutes);
    }
    sb.append(" : ");
    if(seconds<10){
        sb.append("0"+seconds);
    } else {
        sb.append(seconds);
    }
    sb.append(" remaining");
    return (sb.toString());
}
    //--------------------------------------------------------------------------------------------------
public void setTimer(int minutes) {
    if(timerHasStarted)
        return;
    startTime = minutes;
    if(startTime < 1)
        startTime = 1;
    long val6 = (long)startTime*1000;
    String ststring = getDurationBreakdown(val6);
    timeRemaining.setText(ststring);
    timeRemaining.setTypeface(tf);
}
    //--------------------------------------------------------------------------------------------------
public void onClick(View v) {
     if(v==abbtn){
        aboutFragDialog();
    }else if(v==exbtn){
        finish();
    }else if(v==starest){
        if(mTaskFragment.isRunning()){
            mTaskFragment.cancel();
    } else {

            mTaskFragment.start();
    }if(v==mgextbtn){
        mgcusd.dismiss();
     }
    }
}
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
public void aboutFragDialog(){
    AboutDialog  abtdialog = new AboutDialog();
    abtdialog.show(getFragmentManager(),"");
}
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
public void addFragDialog(){
    AddDialog dialog = new AddDialog();
    dialog.minListener = MainActivity.this;
    dialog.secListener = MainActivity.this;
    dialog.tagListener = MainActivity.this;
    dialog.chkbxListener = MainActivity.this;
    dialog.show(getFragmentManager(),"");
}
    //--------------------------------------------------------------------------------------------------
public void workOutResults(){
val3 = (val1*60)*1000;
val4 = val2*1000;
setTimer((val3+val4)/1000);
temp1 = startTime;
temp2 = String.valueOf(temp1);
starest.setEnabled(true);
if(tagval1.isEmpty()){
    savechkbx=false;
}
if(savechkbx){
    TimerDataBaseHandler tdb = new TimerDataBaseHandler(getApplicationContext());
    tdb.addTimer(new TimerClass(tagval1, temp2));
}
LoadSpinnerData();
    }
    //--------------------------------------------------------------------------------------------------
public void updateFragDialog(){
    TimerDataBaseHandler db = new TimerDataBaseHandler(getApplicationContext());
    UpdateDialog updialog = new UpdateDialog();
    updialog.uptgListener = MainActivity.this;
    updialog.uptimListener =  MainActivity.this;
    updialog.upposListener = MainActivity.this;
    updialog.show(getFragmentManager(),"");
}
    //--------------------------------------------------------------------------------------------------
public void updateTimerresults(){
    TimerDataBaseHandler mgdb = new TimerDataBaseHandler(getApplicationContext());
    SQLiteDatabase mgdb1 = mgdb.getReadableDatabase();
    if(mgdb1!=null){
        Cursor mgc = mgdb1.rawQuery("SELECT * FROM timers where _id = "+ upposval, null);
        if(mgc.moveToFirst()){
            mgdb.updateTimer(new TimerClass(upposval, uptagval, uptimeval));
        }
    }
    mgLoadSpinnerData();
}
    //--------------------------------------------------------------------------------------------------
public void deleteaTimer(){
    TimerDataBaseHandler deldb = new TimerDataBaseHandler(getApplicationContext());
    SQLiteDatabase deldb2 = deldb.getReadableDatabase();
    int tagposition1 = s.getSelectedItemPosition()+1;
    String tagposval = String.valueOf(tagposition1);
    if (deldb2 != null) {
        Cursor cccc = deldb2.rawQuery("SELECT * FROM timers where _id = " + tagposval, null);
        if(cccc.moveToFirst()){
            int val0 = cccc.getInt(0);
            String val1= cccc.getString(1);
            String val2 = cccc.getString(2);
            deldb.deleteTimer(new TimerClass(val0, val1, val2));
        }
    }
    LoadSpinnerData();
}
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
    switch(parent.getId()){
        case R.id.timerspinner:
            TimerDataBaseHandler isdb = new TimerDataBaseHandler(getApplicationContext());
            SQLiteDatabase dbsec = isdb.getReadableDatabase();
            int tagposition = s.getSelectedItemPosition()+1;
            isdb.getReadableDatabase();
            Cursor cc = dbsec.rawQuery("SELECT * FROM timers WHERE _id = "+tagposition, null);
            if(cc.moveToFirst()){
                setTimer(Integer.parseInt(cc.getString(2)));
                starest.setEnabled(true);
                replaceFrag();
            }
    }
}
    //--------------------------------------------------------------------------------------------------
@Override
public void onNothingSelected(AdapterView<?> adapterView) {   }
    //--------------------------------------------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
    }
    //--------------------------------------------------------------------------------------------------
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
                   if (id == R.id.action_new) {
                        addFragDialog();
                       return true;
    }else          if (id == R.id.action_discard) {
                        deleteaTimer();
                        return true;
    }else          if (id == R.id.action_edit) {
                       updateFragDialog();
                        return true;
    }
    return super.onOptionsItemSelected(item);
}
    //--------------------------------------------------------------------------------------------------
public void setOSMinListener(String arg){
    val1 = Integer.parseInt(arg);
}
public void setOSSecListener(String arg){
    val2 = Integer.parseInt(arg);
}
public void setOSTagListener(String arg){
    tagval1 = arg;
}
public void setOSCkbListener(String arg){
    savechkbx = Boolean.parseBoolean(arg);
}
public void updateOStagListener(String arg){
    uptagval = arg;
}
public void updateOSTimeListener(String arg) {
    uptimeval = arg;
}
public void updateOSPosListener(String arg){
    upposval = Integer.parseInt(arg);
}

public void replaceFrag(){
    Bundle bundle = new Bundle();
    String tester2 = String.valueOf(startTime).toString();
    Log.i("VertygoEclypse - replaceFrag - Value for counter ", tester2);
    if(tester2.matches("")){
        bundle.putString("SecValue", "15");
    } else {
        bundle.putString("SecValue", tester2);
    }
    FragmentManager rfm = getSupportFragmentManager();
    if(mTaskFragment == null){
    TaskFragment mTaskFragment = new TaskFragment();
    mTaskFragment.setArguments(bundle);
    rfm.beginTransaction().add(mTaskFragment, "task").commit();
    } else {
        TaskFragment mTaskFragment = new TaskFragment();
        mTaskFragment = (TaskFragment) rfm.findFragmentByTag("task");
        mTaskFragment.setArguments(bundle);
        rfm.beginTransaction().add(mTaskFragment, "task").commit();
    }
}
public void initialfrag(){
    Log.i("VertygoEclypse - InitialFrag ","Called");
    Bundle bundl = new Bundle();
    String tester = timeRemaining.getText().toString();
    if(tester.matches("")){
        bundl.putString("SecValue", "15");
    } else{
        bundl.putString("SecValue", String.valueOf(startTime).toString());
    }
    FragmentManager fm = getSupportFragmentManager();
    TaskFragment mTaskFragment = new TaskFragment();
    mTaskFragment = (TaskFragment) fm.findFragmentByTag("task");
    if (mTaskFragment == null) {
        mTaskFragment = new TaskFragment();
        mTaskFragment.setArguments(bundl);
        fm.beginTransaction().add(mTaskFragment, "task").commit();
    }
}
@Override
public void onPreExecute() {
    starest.setText("cancel");
}
@Override
public void onProgressUpdate(int timer) {
    setTimer(timer);
}
@Override
public void onCancelled() {
    starest.setText("Start");
    timeRemaining.setTypeface(tf);
    timeRemaining.setText("0 seconds");
    mTaskFragment.cancel();
    replaceFrag();
}
@Override
public void onPostExecute() {
    starest.setText("Start");
    timeRemaining.setTypeface(tf);
    timeRemaining.setText("Completed");
    mTaskFragment.cancel();
    replaceFrag();
}
     }

Any help on this would be appreciated.

regards

cchinchoy

Was it helpful?

Solution

Once more it would seem that I have answered my own question, with 2 solid days of trial and error on the code, I actually got the idea from another question I posted. The mRunning value needed to be static so that it would be the same for the tasks across the Activity and the Fragment. That being the case changing the code as private boolean mRunning; to this private static boolean mRunning; allow the code to now fire as it is supposed to. Being new to android programming, I am still getting accustomed to the need for the qualifiers such as public, private, static and the sorts. I hope this will help other newbies like myself and help to save the days of pouring over the code to try and find the issue.

thanks once again for the sounding board.

regards

cchinchoy

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top