Android Tutorial AsyncStreamsObject - Send and receive objects instead of bytes

AsyncStreamsObject is a small framework built over AsyncStreams.

Instead of sending and receiving bytes, AsyncStreamsObject allows you to send and receive objects. This makes it much simpler to communicate with other devices.

AsyncStreamsObject uses the WriteStream method of AsyncStreams. This method was introduced in RandomAccessFile v1.5.

You can use AsyncStreamsObject when you implement both sides of the connection.

SS-2013-06-26_10.32.47.png


Supported objects

WriteObject supports: Lists, Arrays, Maps, Strings, primitive types and user defined types.

WriteBitmap allows you to send bitmaps.

WriteFile allows you to send any file.

All the three write methods expect a key (string) and a value (the actual object).

The NewObject event is raised when an object is received. You should use the key to decide how to handle the object. This code is taken from the attached example:
B4X:
Sub astreamO_NewObject(Key As String, Value As Object)
   Select Key
      Case "form"
         Dim m As Map = Value 'Value is a Map
         txtFirst.Text = m.Get("first")
         txtLast.Text = m.Get("last")
         txtAnimal.Text = m.Get("animal")
      Case "simple value"
         Dim number As Int = Value
         ToastMessageShow("Received lucky number: " & number, False)
      Case "image"
         Dim bmp As Bitmap = Value
         Dim r As Rect
         r.Initialize(0, 0, Panel1.Width, Panel1.Height)
         cvs.DrawBitmap(bmp, Null, r)
         Panel1.Invalidate
      Case "file"
         Dim fileName As String = value
         Log("Received file. File size: " & File.Size(astreamO.TempFolder, fileName))
   End Select
End Sub

The ObjectSent event is raised after a value was successfully sent.
B4X:
Sub astreamO_ObjectSent (Key As String)
   Log("Object sent: " & Key)
End Sub

Initializing AsyncStreamsObject

Two steps are required. First you should call AsyncStreamsObject.Initialize and pass the target module and event name:
B4X:
astreamO.Initialize(Me, "astreamO")

Once there is a connection you should call AsyncStreamsObject.Start:
B4X:
Sub StartAstream(s As Socket)
   astreamO.Start(s.InputStream, s.OutputStream)
   SetUIState
End Sub
Note that you can use any type of connection that provides an input stream and output stream.

The Terminated event is raised when the connection is closed.

The attached example connects two devices over the local network. You need to set the IP address of one of the devices and press on the Connect button. Once connect you can send data between the devices.

AsyncStreamsObject class is included in the attached example.
 

Attachments

  • AsyncStreamsObject.zip
    10.5 KB · Views: 3,587
Last edited:

ToolboxZX

Member
Licensed User
Is it possible (or would it be faster) to send the file with B4XSerializator instead? I saw this link after looking around a bit on Erel's suggestion:
https://www.b4x.com/android/forum/threads/b4xobject-b4a-b4j-b4i-objects-serialization.48272/#content
It seems to imply that files might be transferable using it, but I am in need of an example on how to use the WriteB4XObject and ReadB4XObject commands to achieve this. I really am having a hard time finding examples of how to use B4XSerializator. :(
 

ToolboxZX

Member
Licensed User
You don't even need to use B4XSerializator in this case. Just read the file into an array of bytes and send it.

https://www.b4x.com/android/forum/threads/reading-a-file-to-list.62881/#post-397010
Thanks for the quick reply Erel.

Actually Kit I discovered the problem with why the Bluetooth communication was behaving so oddly. As it turns out this problem was also impacting the AsyncStreamsObject "ObjectSent" event from firing correctly. I was able to resolve both issues.

I am working on an adapted set of examples to share (B4A / B4J) so that anyone else wishing to use AsyncStreams can see a complete solution using it and Bluetooth.
 

ToolboxZX

Member
Licensed User
Well, in working on a new Bluetooth example, I stumbled across another issue that should be reproduce-able by anyone. I am hoping to upload the code soon, but in short here is what is happening, using the existing example with the jbluetooth driver instead of the jnetwork one.....
If you connect via bluetooth, you can use any of the buttons to transmit whatever you wish. (send file, send form, send drawing, send number).

That is until you try and send a larger file using the Send File button. (say a couple of megabytes).

As soon as you do that, the transfer starts to get "hung up" sending only a block of data at a time as it sees fit. But there is a caveat to this.

If the first thing you do is send the large file FIRST using the Send File Button, the example will transmit it just find and then allow you to send the smaller files no problems either. However try and send the same large file again and its transfer gets slowed way down and hung up. I have watched the eample in debug mode and it does not appear to be anything in the Main or AsyncStreamsObject modules as that all runs up to the point of departure where you are just waiting for the stream to finish, and watching the activity on the B4A side monitoring bytes recieved.
This has me a bit perplexed......
 
Top