I have a simple game
It displays a list of items that the user selects from with game timer.
I am using native Android widgets in an Activity and a Service to control the game. This has turned out to be cumbersome and my Activity is getting bloated and difficult to maintain.
I have a timer (currently I am using a count down timer)
I need to keep track of scores and rounds
I need to restore the state when the game changes orientation
I need to access a database.
I need different states in the game (buttons cannot be pressed, and sometimes they can)
I need to pull as much out of the Activity as I can
I don't need a canvas, but can someone suggest the best pattern I could use for this? What are the main classes I would have, do I need a game thread etc.
Well, you should have an activity for each level. All of the basic information should be in this activity as variables, the score, level, time, state, etc. You'll need to find a way to put all of them into a bundle when the application closes, and pull all of them out of the bundle when it re-opens. Should be fairly straight-forward.
As for orientation changes, I would lock it to one orientation for now, and get the game working. If it can resume state, then it should be able to handle an orientation change, but to make life simpler at first, I recommend you lock the orientation.
Hope this helps!
Related
How can I control life cycle of QML forms (I mean windows)? I am talking about onCreate, onResume, onPause etc. methods on Android or life cycle of views on iOS. And Can I work this life cycle of QML forms on Android, iOS, Windows 10 Mobile, desktop etc.?
Design of Qt Quick (QML) applications is different from Android ones. There is no difference between views and objects like Button, Text, etc. Every QML object with graphical representation inherits Item and it is possible to define Component.onCompleted and Component.onDestruction functions. They will be executed once object is created and destroyed. If you also need a pause signal I suggest creating functions pause() and resume() in every view you create and create an object that will manage the views - create, destroy, pause and resume them.
Please notice that you need to take care of transitions between views and states yourself. Also as you can create your own QML objects it is worth considering creating a template of a view and then only inherit it.
This will work with every system you deploy the app on.
If you have more questions, need example etc. consider editing the question or leaving a comment.
I want to thank BaCaRoZzo once again for useful tips. I added them to this answer.
I have created an example project that tries to mimic Android app life cycle. This will work with every OS. This is just an example but I think that similar approach may be used in release source. However, first you need to understand the nature of the QML. This is high level language that is already being managed by some other process. It is far different from Java. For example take a look at the fragment of the docs about a state used by background processes:
A Qt Quick application should not usually handle this state at the QML
level. Instead, you should unload the entire UI and reload the QML
files whenever the application becomes active again.
So if I were you I would only save sensitive data when I detect application is going to background. No need to try and unlod views etc. It would be needless uphill struggle becuase QML is not designed for this. Instead let your app be killed if OS needs more memory.
You can find the example project here. You can use it if you want. It contains comments to let you better understand what is going on.
There is a settings screen with multiple categories and each category has 5 to 6 its own settings. Just imagine settings screen of Android OS.
Now, to avoid having Set button on the bottom and trying to implement application of changes immediately upon a user changes any settings (thus to gain speed in the app and to have a better user experience), I thought of having dozens of AsyncTask classes, each implementing just a simple thing.
For example, there is a settings screen with 4 things to set. A user changes setting no.1 and I immediately call AsyncTask for that specific setting in the background. And like this for each change a user makes.
How smart is to do this? Would this overload AsyncTask idea or even come to the point that too many AsyncTasks are called consequently (I read that there is a limit of AsyncTasks that can be called, 5 or something)?
Is it a better design to call 1 AsyncTask with all changes when a user leave the specific settings screen?
Note: I am not asking here how to implement AsyncTask. My questions is directly bound to best design and the best speed of the app, as well the best UX.
You should not use asynctask when you have more than 1/2 operation(s) a minute or so (Quote in Android pushing the limits). You allocate a lot of objects and I peronally found that it looks like the Asynctasks are waiting on another. Maybe use a handler/runnable.
On a site note, you can save all the changes in variables in memory and then periodically save the settings to a backing store. There is nothing faster than just setting an instance variable/array.
In our application when a user switches between modes (different user/ different type of screen) the activity recreates itself (by an explicit call to recreate() ). This behavior was added by a external programmer we hired. He states this is completely normal to do.
The problem I have with this is that 99,9% of all activity state is the same. But when the activity is recreated all data is queried again, consuming quite a bit of time.
Is this a normal pattern? Or is it just as good to only change the data to suit the new situation?
To me it seems kind of strange to manually recreate the whole Activity just to reload some data. In any case just updating the data which has actually changed seems like a much better approach. Especially if you say that it takes quite a bit of time to reload all the data.
The only thing I can think of right now which requires to recreate the Activity is changing the locale or something like, but even that I would not recommend unless it is really necessary. If you are not dealing with configuration changes, e.g. locale, there is no reason to recreate the whole Activity just to reload some data.
I would say it's "normal" in the sense that Activities are recreated all the time by the system, so this just adds another event in which that would happen. Though this is, on it's own, really weird way of going about it. A better, more efficient, cleaner way would be to swap out Fragments on "mode change". You can have a UI fragment for each "mode" and the data stored in a retained Fragment that each one pulls from. This would also help in the sense that the UI doesn't have to be recreated completely with each Fragment swap.
However, if you must, it is an absolute requirement that you follow the same data storage/retrieval methods that you would if the system was killing and recreating the Activity. See How to save state during orientation change in Android if the state is made of my classes?
Basically, you shouldn't be recreating data you already have.
Greetings good people of Stack Overflow.
I am in need of the help of anyone who knows a bit about State Machines and/or Android Development.
So, I've pretty much got the whole design of my app's card game down, I've solved it with a State Machine Design Pattern, I have a CardGame class which in itself manages the different states that the GameState Class can go through and the transitions between them.
Now, my problem is that I do not know how to merge this Design Pattern into my Android App. The main issue is that I can't figure out how to only show a certain Player the actions he can carry out at the certain State the game is at. For example, once the game has just begun, the first Player should only be able to choose 3 of the 15 actions (methods) that the CardGame class allows.
If it where a simple command driven program, once a player would choose an action that he could not execute at a certain time, the program itself would simple printout a "You cannot carry out this action right now, choose another one." or something of that sort, but being it an Android App that manages Buttons and their OnClickListeners, I certainly have not found it to be very easy. I would be grateful if anyone could orient me as to what a viable solution would be, if there is, of course, a way to solve this inconvenient.
Is there a way to manage what Buttons should be printed according to the availability of a certain State's methods? Can one use some sort of flag to notify what the unavailable methods are in any way?
Thanks in advance, Agustin.
Just use a set to store currently valid actions, and update the set (and redraw buttons) when relevant state is changed.
hey people,
I have almost finished writing my first android app. It is a note taking app with add, edit view screens etc...
Initially I was handling moving between screens in a single activity by creating new layout objects such as tables etc... and displaying them.
However after some more reading I have changed my method of moving between screens by using different activities for different screens. However each activity that is called as an intent retrieves a large number of variables from the main activity via setExtra and passes back a large number of variables as well.
Now I want my app to be as efficient as possible and I personally think that handling it all in one activity is less memory hungry and processor intensive although this has the negative of meaning variables are always present (and consuming memory) unlink in a separate activity where they are killed on finish().
But you guys are more knowledgeable then me so what do you think is the best way to do it?
If you launch a new activity for the new screens then you will add that activity to the stack. That way a user can press back and get back to the previous activity. Just changing the layout removes this functionality. I doubt very much you'll have performance issues either way.
Best practice would be to start a new activity, best performance might be to use your current approach.
All your activities will reside and run from the same process. So there is no reason you need to pass around a pile of variables. You could (for example) stick them in a singleton which represents your context. When one activity hands over to another it fills in the singleton and the next one picks up its data from there.
Of course if you ever intend an external activity to interact with your ones you may have to rethink this approach, but I think you'd be fine to keep your views as separate activities. Even if memory is ever so slightly higher, I think it's better to do things correctly and only worry about optimization if and only when it becomes obvious you need it.