停止IntentService有时只能工作

时间:2014-10-20 12:53:26

标签: android listview service 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 %");
        }
    }
}

1 个答案:

答案 0 :(得分: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;
                }