2014-10-20 62 views
0

我有一個小問題,我猜很容易解決。但我現在還沒有得到解決方案。停止IntentService只能有效

我有一個IntentService,它顯示實際下載的文件的狀態,並被填充到一個ListView子項中。一切工作都很好。

從這裏改編:Download multiple files with a progress bar in ListView Android

但只要我想刪除一個啓動下載,因爲它是越來越沒有必要。我的問題發生。 我無法停止IntenService。

我已經嘗試了不同的方法。

How to force an IntentService to stop immediately with a cancel button from an Activity?

How to stop intentservice in android?

在我送一個假信號給DownloadTask,這意味着下載是全成的那一刻。

public static void removeItems(){ 

    startup--; 
    Log.e("Button", "clicked" + "position " + global_position); 

    //tasks contains all DownloadTasks 
    //**sending fake signal here** 
    DownloadingService.DownloadTask t = tasks.get(global_position); 
    t.mProgress = 101;   

    a.remove(global_position); //remove Progress Array_List   

    tasks.remove(global_position); //remove DownloadTask 

    //update the UI 
    listView.setAdapter(mAdapter = new ArrayAdapter<Progress>(act, R.layout.progressbar_list, R.id.textView, a){ 

    }); 

    //trying to stop the IntentService, but goes to the wrong Thread 
    act.stopService(intent); 


    intent = new Intent(act, DownloadingService.class); 
    intent.putExtra("files", mAdapter.getCount()); 

    if(tasks.size() > 0) { 
      //startService causes crash 
     //act.startService(intent); 
    } 



} 

這工作正常,但只有在ListView中有一個孩子。 DownloadTask完成,IntentService停止。但是,只要ListView中有更多子元素,該調用就不會完成下載,並且IntentService將繼續滾動。這導致NullPointer,因爲它要填充ListView子項,我已經刪除。

我的下載服務:

public static class DownloadingService extends IntentService { 
    public static String PROGRESS_UPDATE_ACTION = DownloadingService.class 
      .getName() + ".progress_update"; 

    private ExecutorService mExec; 
    private CompletionService<NoResultType> mEcs; 
    private LocalBroadcastManager mBroadcastManager; 
    private ArrayList<DownloadTask> mTasks; 

    public static volatile boolean shouldContinue = true; 

    private static final long INTERVAL_BROADCAST = 800; 
    private long mLastUpdate = 0; 

    public DownloadingService() { 
     super("DownloadingService"); 
     Log.e("DOWNLOADING", "SERVICE"); 
     mExec = Executors.newFixedThreadPool(20); 
     mEcs = new ExecutorCompletionService<NoResultType>(mExec); 
     mBroadcastManager = LocalBroadcastManager.getInstance(this); 
     mTasks = new ArrayList<Uebersicht.DownloadingService.DownloadTask>(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     doStuff(); 

     if(startup <= 1) { 
      Log.e("startup", "<1" + startup); 
      tasks = mTasks; 

      noOfFilesToDownalod = 0; 
      Log.e("filestodownload", " " + noOfFilesToDownalod); 

      DownloadTask yt1 = new DownloadTask(noOfFilesToDownalod); 
      tasks.add(yt1); 

      Log.e("TASKS", " " + tasks.size()); 

      for (DownloadTask t : tasks) { 
       mEcs.submit(t); 
      } 
      // wait for finish 
      int n = tasks.size(); 
      for (int i = 0; i < n; ++i) { 
       NoResultType r; 
       try { 
        r = mEcs.take().get(); 
        if (r != null) { 
         // use you result here 
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (ExecutionException e) { 
        e.printStackTrace(); 
       } 
      } 
      // send a last broadcast 
      publishCurrentProgressOneShot(true); 
      mExec.shutdown(); 

     }else { 

      Log.e("startup", "elsee" + startup); 
      noOfFilesToDownalod++; 
      Log.e("noOFiles", " " + noOfFilesToDownalod); 
      //noOfFilesToDownalod = intent.getIntExtra("files", 0); 
      tasks.add(new DownloadTask(noOfFilesToDownalod)); 

      Log.e(" tasks", ""+ tasks.size()); 

      DownloadTask t = new DownloadTask(noOfFilesToDownalod); 
      mEcs.submit(t); 

      int n = tasks.size(); 
      for (int i = 0; i < n; ++i) { 
       NoResultType r; 
       try { 
        r = mEcs.take().get(); 
        if (r != null) { 
         // use you result here 
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (ExecutionException e) { 
        e.printStackTrace(); 
       } 
      } 
      // send a last broadcast 
      publishCurrentProgressOneShot(true); 
      mExec.shutdown(); 

     } 
    } 

    private void doStuff(){ 
     if (!shouldContinue) { 
      stopSelf(); 
      Log.e("stopped?", "yeah"); 
      return; 
     } 
    } 

    private void publishCurrentProgressOneShot(boolean forced) { 
     if (forced 
       || System.currentTimeMillis() - mLastUpdate > INTERVAL_BROADCAST) { 
      mLastUpdate = System.currentTimeMillis(); 
      final List<DownloadTask> taskspublish = mTasks; 
      int[] positions = new int[taskspublish.size()]; 
      int[] progresses = new int[taskspublish.size()]; 
      int[] times = new int[taskspublish.size()]; 
      for (int i = 0; i < taskspublish.size(); i++) { 
       DownloadTask t = taskspublish.get(i); 
       positions[i] = t.mPosition; 
       progresses[i] = round(t.mProgress); 
       times[i] = t.minutesleft; 
      } 
      publishProgress(positions, progresses, times); 
     } 

    } 
    private int round(double d){ 
     double dAbs = Math.abs(d); 
     int i = (int) dAbs; 
     double result = dAbs - (double) i; 
     if(result<0.5){ 
      return d<0 ? -i : i; 
     }else{ 
      return d<0 ? -(i+1) : i+1; 
     } 
    } 

    private void publishCurrentProgressOneShot() { 
     publishCurrentProgressOneShot(false); 
    } 

    private synchronized void publishProgress(int[] positions, 
               int[] progresses, int[] times) { 
     Intent i = new Intent(); 
     i.setAction(PROGRESS_UPDATE_ACTION); 
     i.putExtra("position", positions); 
     i.putExtra("progress", progresses); 
     i.putExtra("time", times); 
     i.putExtra("oneshot", true); 
     mBroadcastManager.sendBroadcast(i); 
    } 



    class DownloadTask implements Callable<NoResultType> { 
     private int mPosition; 
     private double mProgress = (100 * Menge.getGroesse())/50; 

     private double rateinsek = Menge.getRate()/60/60; 

     private double mlprosek = (rateinsek * Menge.getRate())/Menge.getGroesse(); 
     private int count = 0; 

     private double ratepromin = Menge.getRate()/60; 
     private double left = Menge.getGroesse()/ratepromin; 
     private int minutesleft = (int) left; 

     public DownloadTask(int position) { 
      mPosition = position; 
     } 

     @Override 
     public NoResultType call() throws Exception { 

      while (mProgress > 0) { 

       mProgress -= mlprosek; 
       Log.e("MPROGRESS", " " + mProgress); 
       Thread.sleep(1000); 
       count++; 
       if(count == 60){ 
        minutesleft = minutesleft-1; 
        Log.e("COUNT", "-1"); 
        count = 0; 
       } 

       // publish progress 
       publishCurrentProgressOneShot(); 

       // we can also call publishProgress(int position, int 
       // progress) instead, which will work fine but avoid broadcasts 
       // by aggregating them 

       //publishProgress(mPosition,mProgress); 
      } 


      return new NoResultType(); 
     } 

     public double getProgress() { 
      return mProgress; 
     } 

     public int getPosition() { 
      return mPosition; 
     } 
    } 
    class NoResultType { 

     NoResultType(){ 

      Log.e("READY", "100 %"); 
     } 
    } 
} 

回答

0

的問題是很容易解決。我只是在DownloadTask的while循環中添加了一個額外的參數。

比較ListView中點擊的位置與ListView中DownloadTask的位置。

只要兩個位置相同,下載就會停止。

while (mProgress > 0 && global_position != mPosition) { 

       mProgress -= mlprosek; 
       Log.e("MPROGRESS", " " + mProgress + " timeleft " + minutesleft); 
       Thread.sleep(1000); 
       count++; 
       if(count == 60){ 
        minutesleft = minutesleft-1; 
        Log.e("COUNT", "-1"); 
        count = 0; 
       }