Android Question How do I re-init an app or restart it to have the latest update of data

Peter Lewis

Active Member
Licensed User
Longtime User
Hi All

I have used B4A to get a customer database from an SQL file (Just the Names) and then display them in a SearchView process so that it can be easily searched and selected.

The problem is that if there is an update on the SQL database, I have to restart the app to see the updates. The customer list is saved to a text file.

Possibly I am going about it the wrong way. If you have time to look at the code and give some advise, I would appreciate it.

Thank you

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: CustomerUpdateSearch
    #VersionCode: 4
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'Activity module
Sub Process_Globals
    Private index As Object
    Private CUSTOMER_LIST = "customer_list", CUSTOMER_NUMBER = "customer_number" As String
End Sub

Sub Globals
    Private SearchView1 As SearchView
    Private ime As IME
    Type TwoLines (First As String, Second As String)
    Dim Writer As TextWriter
   
End Sub

Sub Activity_Create(FirstTime As Boolean)

    Activity.LoadLayout("1")
   
    If FirstTime Then
        FetchCustomerList
                               
        Dim names As List = File.ReadList(File.DirDefaultExternal, "peterh.txt")
       
        index = SearchView1.SetItems(names)
    Else
               
        SearchView1.SetIndex(index)
    End If
    ime.Initialize("ime")
    ime.AddHeightChangedEvent
End Sub


Private Sub IME_HeightChanged (NewHeight As Int, OldHeight As Int)
    SearchView1.ActivityHeightChanged(NewHeight)
End Sub

Sub SearchView1_ItemClick(Value As String)
    Msgbox("Chosen value: " & Value, "")
End Sub

Sub FetchCustomerList
    ProgressDialogShow("Fetching list of Customers")
    ExecuteRemoteQuery("SELECT Name, CustNo FROM Customer ", CUSTOMER_LIST)
End Sub

Sub ExecuteRemoteQuery(Query As String, JobName As String)
    Dim job As HttpJob
    job.Initialize(JobName, Me)
    job.PostString("http://www.@@@@@@/get_data.php", Query)
End Sub

Sub JobDone(Job As HttpJob)
    ProgressDialogHide
    If Job.Success Then
        Dim res As String
        res = Job.GetString
        Log("Response from server: " & res)
        Dim parser As JSONParser
        parser.Initialize(res)
        Select Job.JobName
            Case CUSTOMER_LIST
                Dim CUSTOMERS As List
                CUSTOMERS = parser.NextArray
                Writer.Initialize(File.OpenOutput(File.DirDefaultExternal, "peterh.txt", False))
                Writer.Close
                Writer.Initialize(File.OpenOutput(File.DirDefaultExternal, "peterh.txt", True))
                For i = 0 To CUSTOMERS.Size - 1
                    Dim m As Map
                    m = CUSTOMERS.Get(i)
                    Dim tl As TwoLines
                   
                    tl.Second = m.Get("Name")
               
               
                    Writer.WriteLine(tl.Second)

                Next
               
                Writer.Close
               
            Case CUSTOMER_NUMBER
               
        End Select
    Else
        Log(Job.ErrorMessage)
        ToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If
    Job.Release
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

johndb

Active Member
Licensed User
Longtime User
Hi All

I have used B4A to get a customer database from an SQL file (Just the Names) and then display them in a SearchView process so that it can be easily searched and selected.

The problem is that if there is an update on the SQL database, I have to restart the app to see the updates. The customer list is saved to a text file.

Possibly I am going about it the wrong way. If you have time to look at the code and give some advise, I would appreciate it.

Thank you

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: CustomerUpdateSearch
    #VersionCode: 4
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'Activity module
Sub Process_Globals
    Private index As Object
    Private CUSTOMER_LIST = "customer_list", CUSTOMER_NUMBER = "customer_number" As String
End Sub

Sub Globals
    Private SearchView1 As SearchView
    Private ime As IME
    Type TwoLines (First As String, Second As String)
    Dim Writer As TextWriter
 
End Sub

Sub Activity_Create(FirstTime As Boolean)

    Activity.LoadLayout("1")
 
    If FirstTime Then
        FetchCustomerList
                             
        Dim names As List = File.ReadList(File.DirDefaultExternal, "peterh.txt")
     
        index = SearchView1.SetItems(names)
    Else
             
        SearchView1.SetIndex(index)
    End If
    ime.Initialize("ime")
    ime.AddHeightChangedEvent
End Sub


Private Sub IME_HeightChanged (NewHeight As Int, OldHeight As Int)
    SearchView1.ActivityHeightChanged(NewHeight)
End Sub

Sub SearchView1_ItemClick(Value As String)
    Msgbox("Chosen value: " & Value, "")
End Sub

Sub FetchCustomerList
    ProgressDialogShow("Fetching list of Customers")
    ExecuteRemoteQuery("SELECT Name, CustNo FROM Customer ", CUSTOMER_LIST)
End Sub

Sub ExecuteRemoteQuery(Query As String, JobName As String)
    Dim job As HttpJob
    job.Initialize(JobName, Me)
    job.PostString("http://www.@@@@@@/get_data.php", Query)
End Sub

Sub JobDone(Job As HttpJob)
    ProgressDialogHide
    If Job.Success Then
        Dim res As String
        res = Job.GetString
        Log("Response from server: " & res)
        Dim parser As JSONParser
        parser.Initialize(res)
        Select Job.JobName
            Case CUSTOMER_LIST
                Dim CUSTOMERS As List
                CUSTOMERS = parser.NextArray
                Writer.Initialize(File.OpenOutput(File.DirDefaultExternal, "peterh.txt", False))
                Writer.Close
                Writer.Initialize(File.OpenOutput(File.DirDefaultExternal, "peterh.txt", True))
                For i = 0 To CUSTOMERS.Size - 1
                    Dim m As Map
                    m = CUSTOMERS.Get(i)
                    Dim tl As TwoLines
                 
                    tl.Second = m.Get("Name")
             
             
                    Writer.WriteLine(tl.Second)

                Next
             
                Writer.Close
             
            Case CUSTOMER_NUMBER
             
        End Select
    Else
        Log(Job.ErrorMessage)
        ToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If
    Job.Release
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

I use this code to restart applications (Add it to your Main and call "Restart" to restart the App):
B4X:
Sub RestartMe()
    Activity.Finish
    Dim r, r2 As Reflector
    r.Target = r.GetActivity
    r.Target = r.RunMethod("getApplicationContext")
    r2.Target = r.RunMethod("getPackageManager")
    Dim i As Intent = r2.RunMethod2("getLaunchIntentForPackage", r.RunMethod("getPackageName"), "java.lang.String" )
    r.Target = i
    r.RunMethod2("addFlags",  67108864, "java.lang.int")
    StartActivity(i)
End Sub
I'm sure that there are other simpler methods but this one works for me. This isn't my code but I found this procedure in the forum some time ago.

John
 
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
I use this code to restart applications (Add it to your Main and call "Restart" to restart the App):
B4X:
Sub RestartMe()
    Activity.Finish
    Dim r, r2 As Reflector
    r.Target = r.GetActivity
    r.Target = r.RunMethod("getApplicationContext")
    r2.Target = r.RunMethod("getPackageManager")
    Dim i As Intent = r2.RunMethod2("getLaunchIntentForPackage", r.RunMethod("getPackageName"), "java.lang.String" )
    r.Target = i
    r.RunMethod2("addFlags",  67108864, "java.lang.int")
    StartActivity(i)
End Sub
I'm sure that there are other simpler methods but this one works for me. This isn't my code but I found this procedure in the forum some time ago.

John


I did see this but before I tried it I realised that I would have to make another file on the device with a flag whether the file had been updated or the app would just restart constantly. It has to be a automatic process. I would normally use a memory flag but because the app restarts , I would lose the flag.

Thank you
 
Upvote 0

johndb

Active Member
Licensed User
Longtime User
I did see this but before I tried it I realised that I would have to make another file on the device with a flag whether the file had been updated or the app would just restart constantly. It has to be a automatic process. I would normally use a memory flag but because the app restarts , I would lose the flag.

Thank you
I had the same issues but solved it by adding a flag to the starter service. The starter remains active, only the Main activity restarts. I then check the flag within the Main activity when Main restarts to bypass part of the initialization.

Here is my full Restart with the flag added.
B4X:
Sub RestartMe()
    Starter.MainReboot = True
    Activity.Finish
    Dim r, r2 As Reflector
    r.Target = r.GetActivity
    r.Target = r.RunMethod("getApplicationContext")
    r2.Target = r.RunMethod("getPackageManager")
    Dim i As Intent = r2.RunMethod2("getLaunchIntentForPackage", r.RunMethod("getPackageName"), "java.lang.String" )
    r.Target = i
    r.RunMethod2("addFlags",  67108864, "java.lang.int")
    StartActivity(i)
End Sub
 
Last edited:
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
I had the same issues but solved it by adding a flag to the starter service. The starter remains active, only the Main activity restarts. I then check the flag within the Main activity when Main restarts to bypass part of the initialization.

Here is my full Restart with the flag added.
B4X:
Sub RestartMe()
    Starter.MainReboot = True
    Activity.Finish
    Dim r, r2 As Reflector
    r.Target = r.GetActivity
    r.Target = r.RunMethod("getApplicationContext")
    r2.Target = r.RunMethod("getPackageManager")
    Dim i As Intent = r2.RunMethod2("getLaunchIntentForPackage", r.RunMethod("getPackageName"), "java.lang.String" )
    r.Target = i
    r.RunMethod2("addFlags",  67108864, "java.lang.int")
    StartActivity(i)
End Sub


Hi

It does not like 'Starter.MainReboot = True'
How did you delare Starter ?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

johndb

Active Member
Licensed User
Longtime User
Hi

It does not like 'Starter.MainReboot = True'
How did you delare Starter ?
Here is how the restart with detection works:

Starter Service - Declare the "MainReboot" variable and initially set it to "false".
B4X:
Sub Process_Globals

    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
     
    Public MainReboot As Boolean = False

End Sub

Main activity - perform action based on the state of the starter's MainReboot variable.
Note: Call RestartMe method when you require the Main activity to restart.
B4X:
Sub Activity_Create(FirstTime As Boolean)
 
    if starter.MainReboot then ' Activity has been restarted
 
        ' Clear the flag
        Starter.MainReboot = false
     
        ....
     
    end if
 
    ....
 
End Sub

Sub RestartMe()
    Starter.MainReboot = True
    Activity.Finish
    Dim r, r2 As Reflector
    r.Target = r.GetActivity
    r.Target = r.RunMethod("getApplicationContext")
    r2.Target = r.RunMethod("getPackageManager")
    Dim i As Intent = r2.RunMethod2("getLaunchIntentForPackage", r.RunMethod("getPackageName"), "java.lang.String" )
    r.Target = i
    r.RunMethod2("addFlags",  67108864, "java.lang.int")
    StartActivity(i)
End Sub
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Upvote 0

johndb

Active Member
Licensed User
Longtime User
Ehm. Why do you need to restart an app when only the data changes? I don't get it... (It's like Outlook reboots my pc when a new email arrives) :) Perhaps I did not get a special detail here.
I can't speak for the originator of this thread but I restart the Main activity when there are significant configuration and operational changes that require re-initialization of the Main activity. Restarting is much cleaner than having several decision structures outside of the activity create and resume entry points. I agree that a activity restart due to data changes may not be the most efficient use for the Restarting process but keep in mind that there are several roads to reach a destination. ;)

Cheers,

John
 
Upvote 0
Top