Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes characterist data lost issue #61

Closed
wants to merge 1 commit into from
Closed

Conversation

odahcam
Copy link

@odahcam odahcam commented Mar 9, 2020

This PR refers to #60 and fixes the issue.

Also I would like to suggest the use of a buffered channel (Channel.BUFFERED) instead of just using the broadcast channel with size 1, to avoid data loss again.

@odahcam
Copy link
Author

odahcam commented Mar 10, 2020

Just noticed that on #53 a user suggested using a buffered channel too, appart from using Flow, a buffered channel would be nice for reliability.

@@ -276,7 +276,7 @@ internal class GattConnectionImpl(
}

override fun onCharacteristicChanged(gatt: BG, characteristic: BGC) {
launch { characteristicChangedChannel.send(characteristic) }
runBlocking { characteristicChangedChannel.send(characteristic) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is blocking a thread helping here?

Did you try with #53 instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an awesome question, but I don't have any answer. This just works, rather we like it or not.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try with #53 instead?

Yes, in fact I thought that had solved the issue, but turns out nothing but this solved this crazy behavior.

@sjp4
Copy link

sjp4 commented Apr 12, 2020

Hey - just ran into this and have seen the issue before...

The problem is that Android re-uses the same BluetoothGattCharacteristic instance forever (i.e. in consecutive calls to onCharacteristicChanged, the same instance of the characteristic is passed - but with different values). This means that recipients must read the value from the BluetoothGattCharacteristic before allowing onCharacteristicChanged to return - otherwise the value might have changed by the time they get around to reading it.

In this case, the change to runBlocking works only if the channel is unbuffered, and the finalconsumer of the value reads it immediately upon reading from the channel. Buffering doesn't necessarily solve this either - queued instances would all be updated by Android.

There are a couple of potential solutions, without making it blocking.:

  • Push a deep copy of the BluetoothGattCharacteristic object to the channel (so that it doesn't matter if the original instance value changes in the future). This is the option I went with in a work project (currently messing around on a personal project..).
  • Don't push the characteristic object at all; just push the ByteArray. This does lose the convenience of all of the nice type helper functions that Android provides e.g. getIntValue/getStringValue/etc.

@LouisCAD
Copy link
Collaborator

Hello @sjp4, thanks a lot for sharing your analysis, I now understand how runBlocking can fix it.

I'm not going to merge this quick fix because blocking a thread here can lead to other issues in a mobile app, including slower operation in edge cases.

I think I'll make a deep copy of library created instances of the BGC and BGD classes for now, it will have the benefit of not breaking the API (although other changes might break it a little, namely replacing channels by flows).

@LouisCAD LouisCAD self-assigned this Apr 12, 2020
@LouisCAD LouisCAD self-requested a review April 12, 2020 13:48
@odahcam
Copy link
Author

odahcam commented Apr 13, 2020

Thanks for clearing it out @sjp4, it makes sense now. So it seems this can be solved by applying the same fix as #56. I won't update this because I can't test it right now, so I'll close this PR and hope we can fix it later. Thanks guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants