[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
On Thu, Mar 12, 2009 at 8:08 PM, Streets Of Boston flyingdutc...@gmail.comwrote: I thought that beginBroadcast() would lock the callback-list for modification and finishBroadcast() would unlock it again. This way, N should always be the number of items in this HashMap you were mentioning. Am i correct in this. No, it only locks internally in beginBroadcast() to create the list. If you may have multiple threads calling beginBroadcast(), they need to do their own synchronization, holding your own lock from before calling beginBroadcast() to after finishBroadcast(). -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
Ah, thanks. Either way, it means that the number of items in the list accessed by getBroadcastItem is always equal to N. The problem remains: How can getBroadcastItem(int) return null? On Mar 13, 4:53 am, Dianne Hackborn hack...@android.com wrote: On Thu, Mar 12, 2009 at 8:08 PM, Streets Of Boston flyingdutc...@gmail.comwrote: I thought that beginBroadcast() would lock the callback-list for modification and finishBroadcast() would unlock it again. This way, N should always be the number of items in this HashMap you were mentioning. Am i correct in this. No, it only locks internally in beginBroadcast() to create the list. If you may have multiple threads calling beginBroadcast(), they need to do their own synchronization, holding your own lock from before calling beginBroadcast() to after finishBroadcast(). -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
On Fri, Mar 13, 2009 at 7:27 AM, Streets Of Boston flyingdutc...@gmail.comwrote: Either way, it means that the number of items in the list accessed by getBroadcastItem is always equal to N. The problem remains: How can getBroadcastItem(int) return null? I'm not sure what you mean by either way -- if you are doing this from multiple threads, your threads can clobber the list, which can lead to this kind of problem. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
Ah, now i get it! :-) Indeed, sendProgressCallback can be called from multiple threads. And with your earlier explanation that the beginBroadcast does not do locking (only a brief internal lock), it may explain the problem. In other words, RemoteCallbackList is not thread-safe across multiple calls to it. I should put the broadcast code inside a 'synchronized(mCallbacks) { ... }' block or surround it with a ReentrantLock. Or create mCallbacks instances for each possible thread and have my listeners register with each of them. Thank you very much for your help. Have a great weekend! On Mar 13, 12:58 pm, Dianne Hackborn hack...@android.com wrote: On Fri, Mar 13, 2009 at 7:27 AM, Streets Of Boston flyingdutc...@gmail.comwrote: Either way, it means that the number of items in the list accessed by getBroadcastItem is always equal to N. The problem remains: How can getBroadcastItem(int) return null? I'm not sure what you mean by either way -- if you are doing this from multiple threads, your threads can clobber the list, which can lead to this kind of problem. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
If your callbacks are oneway, the easiest thing to do is put it all in a big synchronized() block. Be aware though that if the callback is into the local process, it will still be synchronous, so holding a lock while doing this can be a problem. Usually the safest thing is to have a handler that you post a message to, which does the callbacks. Then you don't need any locking since the broadcasts are serialized by the handler. On Fri, Mar 13, 2009 at 10:55 AM, Streets Of Boston flyingdutc...@gmail.com wrote: Ah, now i get it! :-) Indeed, sendProgressCallback can be called from multiple threads. And with your earlier explanation that the beginBroadcast does not do locking (only a brief internal lock), it may explain the problem. In other words, RemoteCallbackList is not thread-safe across multiple calls to it. I should put the broadcast code inside a 'synchronized(mCallbacks) { ... }' block or surround it with a ReentrantLock. Or create mCallbacks instances for each possible thread and have my listeners register with each of them. Thank you very much for your help. Have a great weekend! On Mar 13, 12:58 pm, Dianne Hackborn hack...@android.com wrote: On Fri, Mar 13, 2009 at 7:27 AM, Streets Of Boston flyingdutc...@gmail.comwrote: Either way, it means that the number of items in the list accessed by getBroadcastItem is always equal to N. The problem remains: How can getBroadcastItem(int) return null? I'm not sure what you mean by either way -- if you are doing this from multiple threads, your threads can clobber the list, which can lead to this kind of problem. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
Alas, this one is not a one-way interface. It expects a boolean back: False = cancel upload of image, True = continue uploading image. It allows the (remote) client to cancel uploads forcefully. Luckily, the client receiving the call-back can return this answer really fast. The client is not the same process. It is a different app (Activity) in a different process. What is your opinion, in terms of speed/performance: One 'mCallbacks' instance for the Service, sending this callback to its clients, inside a synchronized(...) block or having each a 'mCallbacks' for each thread (max 3)? Which one would be better? The client is always remote (other process). Thanks! On Mar 13, 2:29 pm, Dianne Hackborn hack...@android.com wrote: If your callbacks are oneway, the easiest thing to do is put it all in a big synchronized() block. Be aware though that if the callback is into the local process, it will still be synchronous, so holding a lock while doing this can be a problem. Usually the safest thing is to have a handler that you post a message to, which does the callbacks. Then you don't need any locking since the broadcasts are serialized by the handler. On Fri, Mar 13, 2009 at 10:55 AM, Streets Of Boston flyingdutc...@gmail.com wrote: Ah, now i get it! :-) Indeed, sendProgressCallback can be called from multiple threads. And with your earlier explanation that the beginBroadcast does not do locking (only a brief internal lock), it may explain the problem. In other words, RemoteCallbackList is not thread-safe across multiple calls to it. I should put the broadcast code inside a 'synchronized(mCallbacks) { ... }' block or surround it with a ReentrantLock. Or create mCallbacks instances for each possible thread and have my listeners register with each of them. Thank you very much for your help. Have a great weekend! On Mar 13, 12:58 pm, Dianne Hackborn hack...@android.com wrote: On Fri, Mar 13, 2009 at 7:27 AM, Streets Of Boston flyingdutc...@gmail.comwrote: Either way, it means that the number of items in the list accessed by getBroadcastItem is always equal to N. The problem remains: How can getBroadcastItem(int) return null? I'm not sure what you mean by either way -- if you are doing this from multiple threads, your threads can clobber the list, which can lead to this kind of problem. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them.- Hide quoted text - - Show quoted text - --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: RemoteCallbackList.getBroadcastItem(int) sometimes returns null
m you mean that the value of 'N 'could be larger than the actual elements accessed by getBroadcastItem(i), i.e. HashMap changes while looping over the 'N' items...? For now, i'm check for null and just ignore it. The problem is that it is very hard to reproduce. It happens on rare occasions, but often enough to be problematic. This line has only 3 points in which it could throw a null-pointer exception (the stack-trace reports the NPE on this line, not inside progressChanged(...)): - mCallbacks is null: Not possible. It is declared final and refers to an instance. - qiu is null: Not possible. It is a stack-variable and it has been guarded against null value. - getBroadcastItem(i): The only one left... I thought that beginBroadcast() would lock the callback-list for modification and finishBroadcast() would unlock it again. This way, N should always be the number of items in this HashMap you were mentioning. Am i correct in this. I'll let you know if i can figure out which values for 'i' are problematic :-) Thanks for your help. On Mar 12, 9:27 pm, Dianne Hackborn hack...@android.com wrote: Hm actually could you see if it is the -last- ones that are null? The code that makes the list gets a count from the HashMap, and then iterates through its values and puts them in the array, and returns the original count. So if that count is different than the number it iterated over, that could be a problem. I'll change it to return the actual number it iterated over, but in theory these shouldn't be different. On Thu, Mar 12, 2009 at 6:25 PM, Dianne Hackborn hack...@android.comwrote: The callbacks are just stored in a HashMap, and the entries there are never set null (actually that field is final), so I don't really see how that can happen. Are you sure you aren't potentially doing this loop from different threads without doing your own synchronization? On Thu, Mar 12, 2009 at 6:07 PM, Streets Of Boston flyingdutc...@gmail.com wrote: Hi, I found out that RemoteCallbackList.getBroadcastItem(int) sometimes returns null. I have this code in my Service and it raises a null- pointer exception: ... // instance variable of my Service final RemoteCallbackListIProgressCallback mCallbacks = new RemoteCallbackListIProgressCallback(); ... ... public boolean sendProgressCallback(String imgUri, int albumId, int progressBytes, int progressPercent) { final QueuedImageUpload qiu = getUploadingImage(imgUri, albumId); if (qiu == null) return true; qiu.setSizeUploaded(progressBytes); final int totalSizePercent = mQueues.calculateRemainingSizePercent(); final int N = mCallbacks.beginBroadcast(); try { for (int i = 0; i N; i++) { try { if (!mCallbacks.getBroadcastItem(i).progressChanged(qiu.getID(), imgUri, albumId, progressPercent, totalSizePercent)) { return false; } } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // the dead object for us. } } } finally { mCallbacks.finishBroadcast(); } return true; } This line is the one throwing a nullpointer exception: if (!mCallbacks.getBroadcastItem(i).progressChanged(qiu.getID(), imgUri, albumId, progressPercent, totalSizePercent)) - The mCallbacks is never null. It is declared as final. - The local 'qui' stack-variable is never null. It is guarded by a null-pointer check. That only leads me to conclude that the call getBroadcastItem(i) returns null. However, the documentation states that this method never returns null. Is this a bug in Android? This problem only happens on occasion (I can not reproduce it consistently), but it happens often enough to be of concern for my app. BTW, someone else reported the same problem a while ago: http://groups.google.com/group/android-developers/browse_thread/threa... Thank you. -- Anton Spaans http://soft.antonspaans.com -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them.- Hide quoted text - - Show quoted text - --~--~-~--~~~---~--~~ You received this message