Проблема отменить цикл while в Android - PullRequest
1 голос
/ 08 июля 2011

Прежде всего, извините за не очень описательный заголовок.

У меня есть следующий код, который не работает должным образом (или как я хотел).

Несмотря на то, что я вызываю «Отмена ()», время продолжается ...

private boolean cancelled;

private synchronized Bitmap renderBitmap(PatchInputStream pis){
              File file = new File(Environment.getExternalStorageDirectory()+url);

              FileOutputStream fos=new FileOutputStream(file);
              byte buf[]=new byte[2000];
              int len;
              while((len=pis.read(buf))>0 && !isCancelled() ){
                  fos.write(buf,0,len);
              }
              fos.close();
              if (isCancelled()){
                cancelled=false;
                return null;
              }

              Bitmap bm = saveBitmapToFile(file);
              return bm;
}

public boolean isCancelled(){
    return cancelled;
}

public void Cancel(){
    cancelled=true;
}

Что не так с этим кодом?Я что-то упустил?

Ответы [ 2 ]

2 голосов
/ 08 июля 2011

По крайней мере, в коде есть ошибка параллелизма, которую можно решить, набрав cancelled volatile. В противном случае другой поток не гарантированно увидит новое значение. (Очевидно, это был не тот случай.)

Другая возможность состоит в том, что метод cancel () не вызывается. (Очевидно, это был не тот случай.)

Еще одна возможность заключается в том, что метод cancel () вызывается для другого экземпляра объекта. Попробуйте добавить System.out.println(System.identityHashCode(this)) в метод cancel () и цикл while и посмотрите, выводят ли они одно и то же значение.

0 голосов
/ 08 июля 2011

Используйте volatile в отмененной переменной экземпляра, как предложено @mibollma.Это гарантирует, что ни один поток не использует кэшированную версию переменной.Если это не работает, вы можете попробовать следующее предложение:

Возможно, ваш метод cancel() не вызывается, поток с циклом while не разрешает его.Используйте метод Thread.yield().

Заставляет временно выполняющийся объект потока временно приостанавливать и разрешать выполнение другим потокам.

В вашем whileцикл:

          while((len=pis.read(buf))>0 && !isCancelled() ){
              fos.write(buf,0,len);
              Thread.yield();
          }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...