Download the free trial version
Basic4android Video
Features
Tutorials and manuals
Showcase
Screenshots

Go Back   Android Development Forum - Basic4android > Basic4android > Basic4android Getting started & Tutorials
Documentation Wiki Register Members List B4P Search Today's Posts Mark Forums Read

Basic4android Getting started & Tutorials Android development starts here. Please do not post questions in this sub-forum.

AsyncStreams Tutorial

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 02-03-2011, 01:17 PM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 15,689
Awards Showcase
Basic4ppc Founder 
Total Awards: 1
Default AsyncStreams Tutorial

A new object type is available in the RandomAccessFile library named AsyncStreams.
AsyncStreams allows you to read data from an InputStream and write data to an OutputStream without blocking your program. The reading and writing are done with two separate threads.

When new data is available the NewData event is raised with the data.
When you write data to the OutputStream the data is added to an internal queue and then sent in the background.

AsyncStreams is very useful when working with slow streams like network streams or Bluetooth streams.

If you work with such streams using the main thread your program may hang or block while waiting for a value.
The way we tried to deal with it in the Serial tutorial and Network tutorial is with a Timer that checks whether there are bytes waiting in the buffer. However even if there are bytes available there is a chance that not enough are available and then our program will hang or block until those are available.
Using AsyncStreams is usually simpler and safer.

AsyncStreams can work in two modes. Regular mode and "prefix mode". Both work as described above.

The following code demonstrates a simple program that sends text to a connected device or computer:
Code:
Sub Process_Globals
    
Dim AStreams As AsyncStreams
    
Dim Server As ServerSocket
    
Dim Socket1 As Socket
End Sub
Sub Globals
    
Dim EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    
If FirstTime Then
        Server.Initialize(
5500"Server")
        Server.Listen
        
Log("MyIp = " & Server.GetMyIP)
    
End If
    EditText1.Initialize(
"EditText1")
    EditText1.ForceDoneButton = 
True
    Activity.AddView(EditText1, 
10dip10dip300dip60dip)
End Sub

Sub Server_NewConnection (Successful As Boolean, NewSocket As Socket)
    
If Successful Then
        
ToastMessageShow("Connected"False)
        Socket1 = NewSocket
        AStreams.InitializePrefix(Socket1.InputStream, 
False, Socket1.OutputStream, "AStreams")
    
Else
        
ToastMessageShow(LastException.Message, True)
    
End If
    Server.Listen
End Sub

Sub AStreams_NewData (Buffer() As Byte)
    
Dim msg As String
    msg = 
BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    
ToastMessageShow(msg, False)
    
Log(msg)
End Sub

Sub AStreams_Error
    
ToastMessageShow(LastException.Message, True)
End Sub

'press on the Done button to send text
Sub EditText1_EnterPressed
    
If AStreams.IsInitialized = False Then Return
    
If EditText1.Text.Length > 0 Then
        
Dim buffer() As Byte
        buffer = EditText1.Text.GetBytes(
"UTF8")
        AStreams.Write(buffer)
        EditText1.SelectAll
        
Log("Sending: " & EditText1.Text)
    
End If
End Sub

Sub Activity_Pause(UserClosed As Boolean)
    
If UserClosed Then
        
Log("closing")
        AStreams.Close
        Socket1.Close
    
End If
End Sub
Once there is a connection we initialize the AsyncStreams object:
Code:
AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
Then when there is new data available we convert the bytes to string and show it:
Code:
Sub AStreams_NewData (Buffer() As Byte)
    
Dim msg As String
    msg = 
BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    
ToastMessageShow(msg, False)
End Sub
When the user enters text in the EditText, the text is being sent:
Code:
Sub EditText1_EnterPressed
    
If AStreams.IsInitialized = False Then Return
    
If EditText1.Text.Length > 0 Then
        
Dim buffer() As Byte
        buffer = EditText1.Text.GetBytes(
"UTF8")
        AStreams.Write(buffer)
        EditText1.SelectAll
        
Log("Sending: " & EditText1.Text)
    
End If
End Sub
Prefix mode

When the object is initialized in prefix mode the data is expected to adhere to the following protocol: every message (bytes array) should be prefixed with the bytes array length (as an Int). So if another device sends us a message made of 100 bytes. The stream is expected to include 4 bytes with a value of 100 and then the 100 bytes.
The NewData event will be raised with the 100 bytes. It will not include the 4 prefix bytes.
When you send data with Write or Write2 the bytes length will be added automatically as the prefix of this message.
If you can work in prefix mode, which is usually only possible if you are implementing both sides, it is highly recommended to do so. Under the cover AsyncStreams uses the message length prefix to make sure that the NewData event is always raised with complete messages. If for example it expects 100 bytes and only 60 bytes arrived, it will wait till the other 40 bytes arrive. In regular mode the event will be raised twice and you will need to handle the two parts of the message.
AsyncStreams also handles the case where 100 bytes are expected and more than 100 bytes arrived (which means that there are several messages).

The Error event will be raised if there is any error. You can use LastException to find the reason for the error.
Reply With Quote
  #2 (permalink)  
Old 02-04-2011, 11:02 AM
schimanski's Avatar
Basic4ppc Veteran
 
Join Date: Oct 2007
Location: Germany
Posts: 289
Default

Hello Erel!

I have initialize the Astream with
Code:
  AStreams.Initialize
in the second activity. Than I want to work with the new data in the main activity. But b4a is always looking for the Sub AStreams_NewData (Buffer() As Byte) in the second activity. Is it not possible to get the data in the main-activity? I have declared the Astream in the Main-Activity under Process_Global.

Thanks for help...
__________________
schimanski
--------------------------------------
Device: Motorola Defy, Samsung Galaxy Tab P1000
Dekstop: Asus Eee PC
Reply With Quote
  #3 (permalink)  
Old 02-04-2011, 11:27 AM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 15,689
Awards Showcase
Basic4ppc Founder 
Total Awards: 1
Default

The events are always raised in the same Activity that it belongs.

You can use a Service together CallSub to share an active object between modules (the events should be handled in the Service).
Reply With Quote
  #4 (permalink)  
Old 04-05-2011, 11:09 AM
Newbie
 
Join Date: Oct 2010
Location: Conegliano, Italy
Posts: 8
Default

Hi, where can I download the latest RandomAccessFile library for Basic4PPC? thanks
Reply With Quote
  #5 (permalink)  
Old 04-05-2011, 01:31 PM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 15,689
Awards Showcase
Basic4ppc Founder 
Total Awards: 1
Default

There is no RandomAccessFile library in Basic4ppc. It is a Basic4android library.
Reply With Quote
  #6 (permalink)  
Old 06-20-2011, 02:54 AM
Newbie
 
Join Date: Jun 2011
Posts: 1
Default AStreams.InitializePrefix prefix

Hello,

This is my first message.

I'm just starting to learn how to use this great tool and I need a little of help from any of you.

I managed to make the AsyncStream library to work in a serial communication, but not using the "InitializePrefix" option.

I know it could be a very simple problem for you, but I’d like to know how to get the 4 bytes of the prefix in the correct order from the string length I already have.

Please let me know which sentence could help me on this.

Thank you very much.
Reply With Quote
  #7 (permalink)  
Old 06-20-2011, 08:08 AM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 15,689
Awards Showcase
Basic4ppc Founder 
Total Awards: 1
Default

In order to use prefix mode you will need to have full control over the data that is sent from the serial device. It will not be possible to use prefix mode with most serial devices.
Reply With Quote
  #8 (permalink)  
Old 08-05-2011, 08:33 PM
Junior Member
 
Join Date: Jul 2010
Posts: 28
Thumbs down

Erel,



I am trying to test the AsyncStreams using Android and Basic4PPC desktop with code below:

Android side as the same code that you wrote.

PPC Desktop side:

Sub Globals

End Sub

Sub App_Start
Form1.Show
End Sub


Sub btnSend_Click
Dim test as Byte
test = 56
binary1.New1(Client.GetStream,False)
binary1.WriteByte(test)
Client.Close
End Sub

Sub Button1_Click
Client.New1
Client.Connect(TextBox1.Text, 5500)
label1.Text = "Connection established."
End Sub


===========================


Connection ok

When I send a message from PPC to Android the system shows no information. What is wrong?
Reply With Quote
  #9 (permalink)  
Old 08-06-2011, 02:15 PM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 15,689
Awards Showcase
Basic4ppc Founder 
Total Awards: 1
Default

Make sure to use Initialize instead of InitializePrefix as you are not sending the message length.
Reply With Quote
  #10 (permalink)  
Old 08-06-2011, 02:32 PM
Junior Member
 
Join Date: Jul 2010
Posts: 28
Default

Erel,


I really sorry, but I did not understand what you said.

I also tried to use array but the android application frezzen.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
SQL tutorial Erel Basic4android Getting started & Tutorials 74 05-23-2012 11:27 PM
SQL Tutorial klaus German Tutorials 2 11-11-2011 03:15 PM
SQL Tutorial Erel Tutorials 32 02-07-2011 09:14 AM
GPS Tutorial klaus German Tutorials 3 02-04-2011 06:08 PM
New GPS tutorial Erel Announcements 2 11-05-2007 11:39 AM


All times are GMT. The time now is 10:33 AM.


Powered by vBulletin® Version 3.6.12
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0