2016-10-16 3 views
0

初めてキャンセルされたタスクの開始に問題があります。ビューに入り、タスクを開始すると実行され、フラグメントが最初に破棄されたときにキャンセルされます。しかし、ビューを再入力すると、AsyncTaskは実行されなくなります。AndroidでAsyncTaskをもう一度キャンセルしてから開始してください。

クリーンアップする必要があるクラス状態がありますか?または、FragmentAsyncTaskとバックスタックから削除する必要がありますか?ここで

は、以下の私のコードです:

package com.emijit.lighteningtalktimer; 

import android.content.ContentUris; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import com.emijit.lighteningtalktimer.data.Timer; 
import com.emijit.lighteningtalktimer.data.TimerContract.TimerEntry; 


public class RunTimerFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { 

    private static final String LOG_TAG = RunTimerFragment.class.getSimpleName(); 

    private View rootView; 
    private Uri mUri; 
    private long mTimerId = 0; 
    private Timer mTimer; 
    private RunTimerTask mRunTimerTask; 

    private static final int DETAIL_LOADER = 0; 

    public static String URI = "URI"; 

    public RunTimerFragment() { 
    } 

    static class ViewHolder { 
     TextView intervals; 
     TextView timerSeconds; 
     TextView timerMinutes; 
     TextView timerHours; 

     public ViewHolder(View view) { 
      intervals = (TextView) view.findViewById(R.id.run_timer_intervals); 
      timerSeconds = (TextView) view.findViewById(R.id.timer_seconds); 
      timerMinutes = (TextView) view.findViewById(R.id.timer_minutes); 
      timerHours = (TextView) view.findViewById(R.id.timer_hours); 
     } 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     rootView = inflater.inflate(R.layout.fragment_run_timer, container, false); 

     ViewHolder viewHolder = new ViewHolder(rootView); 
     rootView.setTag(viewHolder); 

     Bundle arguments = getArguments(); 
     if (arguments != null) { 
      mUri = arguments.getParcelable(URI); 
      if (mUri != null) { 
       mTimerId = ContentUris.parseId(mUri); 
       Log.d(LOG_TAG, "mTimerId: " + mTimerId); 
      } 
     } 

     return rootView; 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     getLoaderManager().initLoader(DETAIL_LOADER, null, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     if (mTimerId != 0) { 
      return new CursorLoader(
        getActivity(), 
        TimerEntry.CONTENT_URI, 
        null, 
        TimerEntry._ID + " = ?", 
        new String[] { Long.toString(mTimerId) }, 
        null 
      ); 
     } 
     return null; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
     if (cursor != null && cursor.moveToFirst()) { 
      mTimer = new Timer(cursor); 
     } 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
    } 

    public void startTimer() { 
     mRunTimerTask = new RunTimerTask(); 
     mRunTimerTask.execute(mTimer); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mRunTimerTask.cancel(true); 
    } 

    private class RunTimerTask extends AsyncTask<Timer, Integer, Long> { 

     private final String LOG_TAG = RunTimerTask.class.getSimpleName(); 

     Timer mTimer; 
     int mCurrentSeconds = 0; 
     int mCurrentIntervals = 0; 

     @Override 
     protected Long doInBackground(Timer... params) { 
      Log.d(LOG_TAG, "doInBackground"); 
      mTimer = params[0]; 

      while (mTimer.getIntervals() > mCurrentIntervals) { 
       try { 
        Thread.sleep(1000); 
        mCurrentSeconds++; 
        publishProgress(mCurrentSeconds); 
       } catch (InterruptedException e) { 
        Log.d(LOG_TAG, e.toString()); 
       } 
      } 
      return (long) mCurrentIntervals; 
     } 

     @Override 
     protected void onProgressUpdate(Integer... values) { 
      // do stuff 
     } 


     @Override 
     protected void onPostExecute(Long aLong) { 
      super.onPostExecute(aLong); 
      Log.d(LOG_TAG, "onPostExecute"); 
     } 
    } 
} 

答えて

1

私は問題がcatchブロックであるかもしれないと思います。第三者からのものであるため、mTimer.getIntervals()についてはわかりません。

タスクをキャンセルするとき。 InterruptedExceptionはタスクスレッドで捕捉されます。ループを戻ったり壊したりしなかったので、あなたのループは引き続き動きます。

すべてのAsyncTaskは、サイズが1の1つのスレッドプールにキューイングされるため、別のAsyncTaskを開始してもブロックされます。

0

サンプルでは、​​startTimer()の呼び出しを確認できません。あなたはonResume()をオーバーライドしてstartTimer()を呼び出しますか?

関連する問題