Android Question Running (almost) all code from a service module?

kostefar

Active Member
Licensed User
Longtime User
Dear All,

At the time I started working on my project, I was not too aware of how everything in the main activity module is set on pause whenever the app is not in the foreground. My app depends on constant inputs/outputs from/to a server, and will not do well what it´s supposed to if I don´t put up a service module for all the internet related tasks.
However, to sit and find out which parts that it makes sense to run as a service, and which ones that might as well be left in the main activity would take alot of rethinking the project, which is pretty huge. So, my question is:

Will there be any disadvantages - problems with memory and such - if I just throw (almost) all the code from the main activity module over in a service module? That´d seem a bit clumsy, but be a big time saver.

Thanks in advance for your views on this.
 

KMatle

Expert
Licensed User
Longtime User
I first started having all the code in the main Activity :) Today I move almost all code to services except the views and some checks.

It's easier and of course there are no disadvantages to do so. It's recommended as it is a good style to split the ui (activity) from the data/code. Services can run in the background, too as you have experienced. Some of my apps close the activity and run almost completely in the background. Only if I need to output data to the user I start the activity or throw a notification.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Thanks Kmatie, I´ll have to set up a test project to get familiar with things and then when comfortable apply them to my project!
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
I first started having all the code in the main Activity :) Today I move almost all code to services except the views and some checks.

It's easier and of course there are no disadvantages to do so. It's recommended as it is a good style to split the ui (activity) from the data/code. Services can run in the background, too as you have experienced. Some of my apps close the activity and run almost completely in the background. Only if I need to output data to the user I start the activity or throw a notification.

Why not put the Services Subs() whenever possible, into Code modules and have only global variables and bare bones Subs() in the Services? A lot of my code is reusable so I prefer using Code modules.

I'd really like to see a sample app that uses your approach to see it working for myself. Unless the app is interacting with data outside of the app, like pulling down data from the web, I don't see the need to be running most GUI apps in the background. Maybe I'm missing something. A sample app would certainly clear things up. o_O
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Why not put the Services Subs() whenever possible, into Code modules and have only global variables and bare bones Subs() in the Services? A lot of my code is reusable so I prefer using Code modules.

I'd really like to see a sample app that uses your approach to see it working for myself. Unless the app is interacting with data outside of the app, like pulling down data from the web, I don't see the need to be running most GUI apps in the background. Maybe I'm missing something. A sample app would certainly clear things up. o_O


So the way it sounds to me, there´s nothing else than a better structure for the coders own overview, which justifies code being executed in an activity module.
And for that reason, it may be that I´ll leave subs which are pure math in the activity - after all it may be helpful to not have everything under the same umbrella. On the other hand, many of these "pure math" activities relate to things that are happening on the network, and they should not wait for execution till the application is in the foreground.
I made a simple example for myself to see how it works, that´ll start the service module, which starts a timer that after 5 secs will call one sub in the main activity in order to make a msgbox popup. This is so I had time to put the app in the background and see what happens with such a call to a msgbox when it´s not in the foreground.
The result was fine: It queues the msgbox so that it´ll show as soon as the app is back in the foreground.
After the messagebox, the first timer stops, and another timer starts which logs the datetime.now every second, within the service module - to see if this would be interrupted by the app being in the background. This worked fine, the logging just keeps going.

So in the main activity there´s only the call to service and a sub with the msgbox. The rest is in the service module. I´m not sure if you really want to see this?

And thanks to Erel for clarifying further.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Ok, I´m playing with callsub2 and callsubdelayed2. I´m wondering what would be the best way to handle something like this:

A message comes in from the network which triggers a msgbox2 dialog. This requires that I call a sub in main the activity module showing the msgbox, and since the choice of the user made in the msgbox2 impacts what´s happening next in the service module, I cannot use callsubdelayed2 for this, since this won´t work with returning values.
Now, if the app is on pause, result = CallSub2(Main,"msgbox2_handler",o) (where o is a map with all needed text for the msgbox2 in main) will generate a "null" value error because it does not wait for the box to pop up in the main activity, where I have something like:
B4X:
Sub msgbox2_handler (o As Object)
Dim m As Map
Dim result As Int
m = o
result = Msgbox2(m.Get("Message"),m.Get("Title"),m.Get("Positive"),m.Get("Cancel"),m.Get("Negative"),m.Get("Icon"))
Return result
End Sub

. So I could make a detection of if the app is on pause and then let the code execute when not or I could pass the returned result of the msgbox2 via a global variable and use callsubdelayed2 instead.. or something else.. opinions?

Then there´s another problem: If the app is not paused so that the msgbox2 is showing without being touched, then if the app pauses (for instance if switching another app to the foreground) and resumes again when back in foreground, the msgbox2 is gone. Any existing workaround for this?

Thanks in advance!
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
First you need to decide what should happen if the app is in the background. Do you really want to show an activity and msgbox in that case? It is considered bad practice to start an activity when the user doesn't expect it.

You can use IsPaused to check whether there is any visible activity.

You can use CallSubDelayed to call a sub in the activity and then CallSub or CallSubDelayed to call a sub in the service from the activity with the result. It will be more flexible.

Modal dialogs are dismissed when the activity is paused. If it is problematic for you then don't use a modal dialog. Show a regular panel over the layout instead. Another option is to show the msgbox again in Activity_Resume.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
First you need to decide what should happen if the app is in the background. Do you really want to show an activity and msgbox in that case? It is considered bad practice to start an activity when the user doesn't expect it.

You can use IsPaused to check whether there is any visible activity.

You can use CallSubDelayed to call a sub in the activity and then CallSub or CallSubDelayed to call a sub in the service from the activity with the result. It will be more flexible.

Modal dialogs are dismissed when the activity is paused. If it is problematic for you then don't use a modal dialog. Show a regular panel over the layout instead. Another option is to show the msgbox again in Activity_Resume.

Thanks Erel, I get what you´re saying. This one msgbox2 dialog needs to be forced to the foreground though - even if the app is paused. It´s a request for an incoming call, and also how it´s done on for instance skype. Is there a way to force a paused activity to resume? That´s what I would need for this I think.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Call StartActivity to show an activity even if the app is in the background.

I tried it already but it wouldn´t work, but thanks to you confirming it, I knew I had to stay on this track and figured that the reason is that it takes a while for the activity to resume, and at the point where it´s resumed the code to call the msgbox2 sub has already been executed. So I guess I gotta rethink how the msgbox2 dialog is called.. probably by instead using "result =" from the main activity and then using callsub2 to send back the result to a sub in the service module.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Don't use a modal dialog.

You can use a transparent activity if you like with a panel.

Ok, now I got it working with a msgbox in activity_resume sending back the response to a sub in the activity module. The main reason you recommend rather to use a panel is because how the msgbox disappears if app is paused, right?
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User

Thanks Erel.

To everybody who´s curious about how easy it is to "migrate" code at such a late stage from all-in-main-activity to most-in-service-module, I can tell you that it´s NOT. Alot of my code is in button_click events, which have to be handled in an activity module, so if you´re like me who don´t gently create small subs for everything, it´s alot of things to change and find out where belongs. Learning lesson is to consider from the beginning of a new project whether if it will contains parts that should never be paused, and design the code that way.
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Thanks Erel.

To everybody who´s curious about how easy it is to "migrate" code at such a late stage from all-in-main-activity to most-in-service-module, I can tell you that it´s NOT. Alot of my code is in button_click events, which have to be handled in an activity module, so if you´re like me who don´t gently create small subs for everything, it´s alot of things to change and find out where belongs. Learning lesson is to consider from the beginning of a new project whether if it will contains parts that should never be paused, and design the code that way.

I don't think most developers think of this when they first start writing B4X apps and a tutorial would help developers organize their applications properly. The tutorial could describe taking an existing app written the old fashioned way and changing it to be more service module centric so they can see a before and after approach. The tutorial would of course list the pros and cons of writing an app each way. I think it would be valuable if this tutorial was part of the Users Guide since that is what most newbies start with. Hopefully someone has the time and knowledge to write it. Hmmm??? :rolleyes:
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
I believe that if you´ve read the full Users Guide (I didn´t, I use it as an encyclopedia), then you´ll know how to do things right. And I think there´s no cons in getting things right from the beginning using a service module. There´s alot of stuff that´s super important, depending on what your objective is, and the only way to do things right is either go through the whole User Guide or with trial and error. The importance of using service modules is something you´d never think of till much later, unless you´re experienced in b4a, or you´ve read the User Guide. So, my point is: If there´s some nice tutorial here about service modules and how important they are to consider before starting on a project, it won´t be seen by new b4a developers because they´re not aware of the importance till it´s too late. That´s how it works for most of us I think, you do alot of trial and error, and get better and better.
But, I think that our little discussion here may help others, should they be so lucky to stumble over it :D
 
Upvote 0
Top