0

我遇到了 Fragment 和 AsyncTask 的问题。问题是我正在创建一个片段来运行 AsyncTask 来运行计时器。该代码独立于我的所有其他代码工作,我已经对其进行了多次测试。问题是当我将新代码放入我的应用程序时,此时我得到一个空指针:

        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();
     }
    }
}

推动错误的实际行是:if(mTaskFragment.isRunning()){. 此代码链接到以下内容:

       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();
    }
}

从以下调用:

        @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();
            }
    }
}

上面的代码就足够了,在我的 TaskFragment Activity with Logs 中,我可以看到我发送的变量被用作倒计时的 startTime,如下所示:

        @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());
}

话虽如此,此代码可作为独立代码运行并提供预期结果。问题是当我将它连接到我的应用程序时,似乎虽然值移动到 Fragment 我无法启动 Asynctask。以下是我到目前为止的代码。

这是TaskFragment.class包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;
    }
}
    }

MainActivity 有点长,所以我希望没有人不高兴,但我认为如果没有看到代码,就无法做出正确的评估。

    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();
}
     }

对此的任何帮助将不胜感激。

问候

钦乔伊

4

1 回答 1

1

再一次,我似乎已经回答了我自己的问题,在代码上进行了 2 天的试验和错误,我实际上是从我发布的另一个问题中得到了这个想法。mRunning 值需要是静态的,以便跨 Activity 和 Fragment 的任务相同。在这种情况下,将代码更改为private boolean mRunning;允许private static boolean mRunning;代码现在按预期触发。作为 android 编程的新手,我仍然习惯于需要诸如 public、private、static 等限定符。我希望这将帮助像我这样的其他新手,并帮助节省倾注代码以尝试查找问题的日子。

再次感谢您的共鸣板。

问候

钦乔伊

于 2014-01-21T02:36:21.043 回答