Android Tutorial Two activities example

An improved version, based on CallSubDelayed is available here.
This example demonstrates how to work with more than one activity and how to pass information between the activities.
In this example we have two activities. One activity is the "main" activity. When the user presses a button a "list" activity will be displayed. The user will choose an item from the list and then return to the main activity:

two_activities.png



It is recommended that you first read the Activities life cycle tutorial if you haven't read it before.

In order to add a new or existing activity to your project you should choose Project - Add New / Existing Module.

Variables declared in Sub Process_Globals are public variables and can be accessed from other activities. Therefore we will save the chosen value in such a variable.

When the user presses on the "choose item" button we open the second activity:
B4X:
Sub Button1_Click
    StartActivity(Activity2)
End Sub
When we open an activity the current one is first paused and then the target activity is resumed (and created if needed).
You can see it in the logs:

twoactivities_logcat.png


The second activity is pretty simple:
B4X:
Sub Process_Globals
    Dim result As String
    result = ""
End Sub

Sub Globals
    Dim ListView1 As ListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("2")
    For i = 1 To 100
        ListView1.AddSingleLine("Item #" & i)
    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ListView1_ItemClick (Position As Int, Value As Object)
    result = value 'store the value in the process global object.
    StartActivity(Main) 'show the main activity again
End Sub
When the user presses on an item we store the value in the 'result' variable and we return to the main activity.

The main activity Resume event will be raised. So in this event we check if 'result' variable is not empty and change the label's text.
B4X:
Sub Activity_Resume
    If Activity2.result.Length > 0 Then
        Label1.Text = "You have chosen: " & Activity2.result
    Else
        Label1.Text = "Please press on the button and choose an item."
    End If
End Sub
In more complex applications with more than two activities you can use a process global variable in the main activity. Before starting an activity you can set this variable to some constant and then in Sub Activity_Resume check the value of this variable to know which activity was started and act accordingly.

The project is attached.
 

Attachments

  • TwoActivities.zip
    6.7 KB · Views: 6,095

derez

Expert
Licensed User
Longtime User
Is it possible to use subs from the main in the second module ? I tried using main. before the name of the sub but it still shows an error. "Public" is not recognized...
 

derez

Expert
Licensed User
Longtime User
Erel
I'm afraid this is not exactly as you say.
I added a module with another activity, switched to this activity while running and when I returned to the main activity it continue to work as if nothing happened, although I haven't done anything to save and resume, or kept any variables at process globals (except GPS).
This way is perfect for this application, if only I could use the subs from the main module.
 

schimanski

Well-Known Member
Licensed User
Longtime User
Hello Erel!

I have one question about this thread. I want to rewrite my app from wm to android and now I dont' know, if I write it in one ore different activities. My app has several Forms, one main Form and the other forms are different forms for settings. When the main activity is a GPS-activity and I open a settings-activitiy, does the GPS-activity then stops working? If the GPS will stop, I think, that it is better to write everything in one activity and only load the new layouts to make the users settings.....
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm afraid this is not exactly as you say.
I added a module with another activity, switched to this activity while running and when I returned to the main activity it continue to work as if nothing happened, although I haven't done anything to save and resume, or kept any variables at process globals (except GPS).
This way is perfect for this application, if only I could use the subs from the main module.
The OS may or may not destroy your activity while it is in the background, depending on the resources available.

For the discussion, why do you need to call the other activity sub?

I have one question about this thread. I want to rewrite my app from wm to android and now I dont' know, if I write it in one ore different activities. My app has several Forms, one main Form and the other forms are different forms for settings. When the main activity is a GPS-activity and I open a settings-activitiy, does the GPS-activity then stops working? If the GPS will stop, I think, that it is better to write everything in one activity and only load the new layouts to make the users settings.....

The GPS is a process variable. It will not stop unless you stop it in Activity_Pause.
Usually you will want to stop it in Activity_Pause and start it in Activity_Resume (which will be called when the activity returns to the foreground).

You can also use one Panel for each of your layouts (panels can also load layout files).
 

derez

Expert
Licensed User
Longtime User
For the discussion, why do you need to call the other activity sub?

The main activity is used for displaying the map, the other is for settings, handling of waypoints etc. The other option is to use a panel, to cover the whole display area and handle the settings from there. I chose second option after I couldn't use the subs from the main module, but now I have a problem with the panel not moving out of view when it is not needed...
 

peacemaker

Expert
Licensed User
Longtime User
BTW, how to delete non-actual anymore layout from the designer ? Excepting manual editing .b4a and deleting .bal.
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
But how to make that first main activity having timers and other periodical «activity» is going working when other set active?
I mean to have background working application.
 
Last edited:

kkolle

Member
Licensed User
Longtime User
Hi Erel!

My name is Karl-Heinz and I´m chief of development of a leading german company for telematic software.
At the moment we are checking several evironments for converting our existing software to android.

At the moment Basic4android seems to be a very powerful tool.
But when can we expect the next version? We need services and maybe widgets!

What do you think about a donation to speed up the release date :)

Thanks for your answer!
 

Jim Brown

Active Member
Licensed User
Longtime User
Hi developers

I am working with 2 activities but am trying to figure a good way of closing the app from the "main" activity without the second activity re-appearing

Lets assume two activities are created:

main
activity2


I want the "BACK" button to act as an app quit, closing everything, but only when in the "main" activity
When in "activity2" the back button should act as a 'go back to main activity'

At the moment I use StartActivity() to bounce between the two. I am not trapping the BACK key
The thing with this method is, when you press BACK from the "main" activity the "activity2" will appear. This makes sense in that the "main" has been killed (leaving "activity2" to fend for itself)

I tried using a flag within Resume() of "activity2" so it would know that the main activity had closed. You still get to see the activity before things close so it kind of looks a little buggy or ugly

Ideally I would like to do something like this
B4X:
' "main" activity
Sub Activity_Pause (UserClosed As Boolean)
  If UserClosed=True Then activity2.Finish
End Sub
The problem is, activity2 cannot be accessed in this context

So, I could trap the BACK key, although I attempted this before and got stuck in a whole world of mess whereby I could not quit at all(!)

Another option is to hide activity2 contents when leaving and show them upon entering again. This could be done but right now everything is parented to the activity. Also the background is a gradient
Possible I could LoadLayout() and load up a blank template

My final option is to call Activity.Finish whenever I leave Activity2
This I find gives a slight delay though when going back into the activity because it needs to be re-created again

Your thoughts?
 

klaus

Expert
Licensed User
Longtime User
What do you have in Activity2 ? Do you really need it ?
Couldn't you work instead with Panels in the main Activity ?
It is possible to set a Layout file for each Panel and load them with Panel.Layout.
So you won't have the trouble when closing the application.

Best Regards.
 

Jim Brown

Active Member
Licensed User
Longtime User
What do you have in Activity2 ? Do you really need it ?
Couldn't you work instead with Panels in the main Activity ?
It is possible to set a Layout file for each Panel and load them with Panel.Layout
Klaus,
I tend to like splitting things off into their own activities. It helps me keep the app manageable
Having said that I do like the idea of using panels. I will have a play

You can use ExitApplication to kill the current process and quit all activities
I avoided that command Erel because of the warning about letting the O/S do its thing. Are there any potential side effects such as memory leaks or the application staying resident?
If not I will use this command (which will save me a whole world of pain)
Thanks!
 
Last edited:

margret

Well-Known Member
Licensed User
Longtime User
Two or more activites

Hello,

I am having the same problem. When switching between the two activites or more. I need over 6 other activites because the number of options I give in settings takes up the whole screen on the tablet's 7" screen 1024 x 600. I do use the ExitApllication in the Main activity when I am done and all the other activites are still open and have to be closed with the systems back button one at a time. So exitapplication does not kill all the other activities. Also, the Process_Globals does not work for me. Docs says these varibles here are known to all modules. I get undefined errors every time I try to compile saying they can't find the varibles. I am knew, about a week into B4A but have developed code for 25+ years.

So now my question. Can you, and if you can, how can you use the designer to create your panel screens without it creating an activity? Do you just delete the activity once you create your layout file. Does it reset the parent to the panel at that point?

The only way I see the two or more activities working for me is to write the data I need to a file and use activity.finish to close each time, then load the data from the main activity to see the selections that were made. Any help or thoughts would be great!

Thanks,

Margret
 
Top