Problem to cancel a "while" loop in Android
First of all, sorry for the not-very-descriptive title.
I've got the following code that it's not working properly (or as I'd wanted).
Even though I call "Cancel()", the while goes on...
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;
}
What's wrong with this code? Am I missing something?
At least the code has a concurrency bug which can be solved by making cancelled
volatile
. Otherwise the other thread is not guaranteed to see the new value.
(Apparently this was not the case.)
Another possibility is that the cancel() method is not called. (Apparently this was not the case.)
Still one more possibility is that the cancel() method is being called on a different object instance. Try adding System.out.println(System.identityHashCode(this))
to both the cancel() method and the while loop and see if they print the same value.
Use volatile
on the cancelled instance variable as suggested by @mibollma. This will assure that no Thread is using a cached version of the variable. If that does not work, you can try the following suggestion:
Your cancel()
method is probably not being invoked, the Thread with the while loop is not permitting it. Use the Thread.yield()
method.
Causes the currently executing thread object to temporarily pause and allow other threads to execute.
In your while loop:
while((len=pis.read(buf))>0 && !isCancelled() ){
fos.write(buf,0,len);
Thread.yield();
}
精彩评论