Other My First Official App - Advice Please


Well-Known Member
Licensed User
Hello friends, hope you all had a pleasant Christmas/New Year!

I've finally got my UPNP Browser App finished and listed on the Play Store, the source code can be found here UPNP Browser - Source Files Included (located on the share your creations forum).

I'd be gratefull if you could spend a moment or two to test it and rate my app, link to the play store provided in the thread shown above.

I also need some advice please. I'd like to implement threading into the XOM parser sections of code so that the front end stays responsive and it will allow me to abort the parsing operation should the user make a selection or navigate away before the entire list is parsed. The section of code is as follows...

#Region -------------------------[ Extract Results Detail ]-------------------------
Private Sub ResultsXOM_BuildDone(ResultsXOM_Doc As XOMDocument, Tag As Object)
    ' Event raised when ResultsXOM document completed or failed
    If ResultsXOM_Doc.IsInitialized Then
        ' Get root node and retrieve results
        Dim rootNode As XOMElement = ResultsXOM_Doc.RootElement
        ' XOM document creation failed
        Debug.debugLog("XOM_Doc is not initialized: " & LastException) 'DEBUG
    End If
End Sub

Private Sub GetBrowseResults(parentNode As XOMElement)
    ' Initialise browseResults clearing it of past data if browseReset is set
    If UPNP.browseReset = True Then
        ' Initialise container to add "Previous menu..." entry at top of every list
        Dim container As itemContainer
        container.title = "Previous menu..."
        container.itemClass = "return"
        container.location = ""
        UPNP.browseResults.Put("Previous", container)
    End If
    ' Loop through all container items and store in browseResults Map, use id = key
    Dim containerNodes As XOMElements = parentNode.GetChildElements
    Dim i As Int
    Debug.debugLog("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") 'DEBUG
    For i = 0 To containerNodes.Size - 1
        ' Initialise container to store item details
        Dim container As itemContainer
        ' Get title value
        Dim containerNode As XOMElement = containerNodes.GetElement(i)
        ' Store container id (Unique key to access the item)
        Dim key As String
        key = containerNode.GetAttributeByName("id").Value
        Dim nameSpace As String = "http://purl.org/dc/elements/1.1/"
        Dim titleNode As XOMElement = containerNode.GetFirstChildElementByNameAndNamespace("title", nameSpace)
        container.title = titleNode.Value
        ' Get class value
        Dim nameSpace As String = "urn:schemas-upnp-org:metadata-1-0/upnp/"
        Dim classNode As XOMElement = containerNode.GetFirstChildElementByNameAndNamespace("class", nameSpace)
        container.itemClass = classNode.Value
        ' Get res value (location to stream content)
        Dim nameSpace As String = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
        Dim resNode As XOMElement = containerNode.GetFirstChildElementByNameAndNamespace("res", nameSpace)
        If resNode.IsInitialized Then
            container.location = resNode.Value
            ' Attempt to get resolution information
                container.strResolution = resNode.GetAttributeByName("resolution").Value
                Debug.debugLog("xxx- Resolution unavailable -xxx") 'DEBUG
            End Try
            container.location = ""
        End If
        ' Check if item has previously been added to the currently playing playlist
        If Music.playList.IsInitialized Then
            Dim track As trackInfo
            ' Returns an un-initialised track if not found
            track = Music.GetTrackWithKey(key)
            ' Set selected status if track found in playlist
            If track.IsInitialized Then container.selected = True
        End If
        ' Store id and container info in browseResults list (ignore trailers)
        If titleNode.Value.ToLowerCase.Contains("-trailer") = False Then
            UPNP.browseResults.Put(key, container)
            Debug.debugLog("Container-->[id=" & key & "] " & _
                                       "[title=" & container.title & "] " & _
                                       "[class=" & container.itemClass & "]" & _
                                       "[resolution=" & container.strResolution & "]" & _
                                       "[location=" & container.location & "]") 'DEBUG
        End If
        ' Refresh display every 5th record (to catch click events whilst updating records)
        If i Mod 5 = 0 Then
        End If
    ' Display first browsed item(s) (LoadCustomListView will be called again if user scrolls clv)
    Debug.debugLog("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") 'DEBUG
    If UPNP.browseReset = True Then CallSubDelayed2(Main, "LoadCustomListView", Main.clvJumpPosition)
    Debug.debugLog("##### DEVICE DATA DISPLAYED #####") 'DEBUG
    ' Check if more items available to browse
    If (UPNP.browseStartingIndex + UPNP.browseRequestedCount) < UPNP.browseLimit Then
        CallSub2(Main, "progress_Update", True)
        ' Turn off browseReset (allows future results to be appended to the list)
        UPNP.browseReset = False
        ' Adjust starting index for browse request
        UPNP.browseStartingIndex = UPNP.browseStartingIndex + UPNP.browseRequestedCount + 1
        CallSub3(UPNP, "BrowseServer", UPNP.browseID, False)
        CallSub2(Main, "progress_Update", False)
    End If
End Sub
#End Region
How do I go about making the "GetBrowseResults(parentNode As XOMElement)" run in its own thread? All my attempts have resulted in errors that I didn't understand!



Licensed User
What were the errors? You can't debug code with a thread in it, it will need to be run in release mode to work.


Well-Known Member
Licensed User
I'll have to try again. The errors were during compile because the syntax or my approach was wrong. Can I still write to the log when running on another thread?