【问题标题】:Stopping IntentService only works sometimes停止 IntentService 有时才有效
【发布时间】:2014-10-21 18:56:57
【问题描述】:

我遇到了一个小问题,我想这很容易解决。但我现在真的没有得到解决方案。

我有一个 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 %");
        }
    }
}

【问题讨论】:

    标签: android listview service intentservice


    【解决方案1】:

    这个问题很容易解决。我只是在 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;
                    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多