My Android app hangs when it tries to open a file using the BinaryStream.Open method. Checking the documentation, it reads the following for the open method:
“This method is not supported for Android.”. Fine, at least I know the reason of the hang.
I fail to find another method to read the file, although the Create command is well supported to write to the file.
What am I missing?
try
Var f As FolderItem=GetPasswordFile(False)
if f<>nil then 'not f.exists is taken care in the above function
Var b As BinaryStream=BinaryStream.Open(f)
EnteredPassword=b.Read(b.Length,Encodings.UTF8)
b.Close
end if
Catch e
MessageBox e.ErrorNumber.ToString 'For debugging, but never went there
end try
(the password is currently saved clear, I’ll change that later)
And the GetPasswordFile function:
Public Function GetPasswordFile(ForSaving As Boolean) As FolderItem
Var f As FolderItem
'I already tried the commented folders below, not knowing where the issue lies:
'f=SpecialFolder.ApplicationSupport
'f=SpecialFolder.Caches
f=SpecialFolder.Documents
if f=nil then Return nil
if not f.Exists then
if not ForSaving then Return nil 'Folder doesn't exist
f.CreateFolder
end if
f=f.Child(".com.amug.commliste.mdp") 'An invisible file
if f=nil then Return nil 'Unexpected problem
if (not f.Exists) and (not ForSaving) then Return nil 'File doesn't exist
Return f
End Function
Yet the documentation says it shouldn’t (Open isn’t supported on Android).
How does your working code look different to mine?
Since the beginning, there’s something weird with this, because the same app works fine on my mother’s Android phone.
I don’t know Android enough to be aware of some kind of “antivirus” that may flag my app’s behaviour and make it hanging. Could this be the cause?
The “if f<>nil then” statement avoids using the file further if it’s nil. I’m not raising a further exception because I don’t need it (I just silently ignore the file when it doesn’t exist).
Anyway, my app hangs after the file is created (either just after saving it or when killing and re-opening the app (while attempting to read it)), not when the file doesn’t exist.
Ok, this seems to confirm BinaryStream.Open is supported (the documentation states the opposite).
So why does the app hang on my phone?
Since MessageBox is asynchronous in Android, I can’t use that for debugging the real app. What other technique could I use, knowing debugging from Xojo isn’t an option for me?
The documentation doesn’t mention how to retrieve the output of this method; it only mentions Mac, Windows and Linux.
Would be great to use that, indeed.
I don’t think so, it’s rather me who has a problem with Android…
It turns out the issue isn’t about BinaryStream or files, but concerns delegates and/or AddressOf. I’m sorry to have bothered with the wrong issue; the fact that Xojo won’t debug Android apps on my computer (see my other thread, unsolved), neither in the simulator nor on a real device, makes me guessing a lot, trying slight modifications to my code, uploading the app to my website to install on my phone and watch whether the app hangs or not (and, when it hangs, I can’t see MessageBoxes to have a hint at which step it hung). It’s rather a nightmare.
My code use AddressOf a lot, so I have a module I can use in desktop, mobile and web. After lot of experimenting, I’ve found that these AddHandlers, AddressOf, Delegates and Timer.CallLater things hang at random times, often.
It’s puzzling: if I call the Init method alone, which contains AddHandler and AddressOf calls, the app seems to not hang. If I first load the saved password before calling Init, the Init method hangs.
Thanks to Ivan for having provided a solution to my non-working debugging for Android in Xojo, I’ve been able to spot on a bug in my project.
It was odd at first, because the debugger broke on a call to a method, with no parameter, with an OutOfBounds exception. That’s a Xojo issue. The exception was inside the called method but it wouldn’t break there nor stop at breakpoints.
In the offended code, there are two calls: string.left(1) and string.middle(1). It turns out that these throw an exception if the string is empty, unlike other platforms.
I’m writing all this in case someone else encounters the same weird behaviours.
Xojo/RB has always dealt with strings by returning empty results when an out of range condition happens (NthField, Left, etc.).
While they’re an array of characters, they are treated like a stream; it makes sense to me.
Xojo <> RB. The trend is toward exceptions. Maybe they haven’t gone there yet in order to extend the window of compatibility, but it is coming. They didn’t have to deal with backward compatibility for Mobile, but the rest will follow suit. I thought it had happened already.
I personally don’t hope so. I don’t like this trend. But, well, I don’t want to start a discussion on that subject, because they’ve already been done several times in the past, and I know each group (in favour/against) have strong arguments and the discussion won’t be constructive.
That would be stupid, IMO. An empty string is still a valid string. string.left(1) and string.middle(1), with string being empty, should simply return empty strings.