Handling program flow for an application - android

I am currently trying to write a simple application very similar to this:
http://lab.andre-michelle.com/tonematrix
My main problem is that I do not know how to handle the general program flow. Traditionally, I would use a loop inside the main function that handled the drawing and updated the state and everything. The way the android framework works is a bit confusing since the access points into the program are the various onSomething() functions. This is quite confusing for a beginner.
How do I keep track of time and how do I know how when to move to the next square column?
Do I HAVE to use threads? Is there a single thread solution, similar to the single loop approach?

You can use timers, they do already run in their own threads.
You can also use handlers for timed execution.
In case of the sample program u linked to, you would add something with onTouch and have a timer running in the background to periodically play the tune.
The activity lifecycle should be seen as the lifeline of your program not so much of the code in it.
How to keep track of time ?
System.currentTimeMillis();

Related

Can I use getApplicationContext() object for synchronizing?

When I have a small single block of code that should not get executed in parallel in my application (eg. when an Activity gets killed and restarted when the user turns the device), would it be possible to put it into a code block synchronized to the Application Context?
As far as I understood, this should work as long as the application context object stays the same over the full lifecycle of the app – but does it? I haven't found anything about its lifecycle.
synchronized (getApplicationContext()) {
if (piCacheFileDoesNotExist() == true) {
calculatePIandStoreToCacheFile(); // This is an example only...
}
}
Would that example be a possible way (especially when the task is too small to create an extra Service for it) or would it be a bad idea because of anything I've missed?
I believe you're trying to solve the wrong problem with the wrong tools.
syncrhonization: This is often use to make some code "thread-safe-ish" by ensuring an "object" (any) can act as a gatekeeper. If you can guarantee that there's only one instance of some object, then multiple threads could ask said unique object "are you free so I can run this code?" if the answer is yes, then the code is executed on that thread, otherwise, the thread must wait until the object frees it. Think of a semaphore.
synchronized(XXX) { ... } is doing that. It ensures ... is not executed until XXX says so. (note: this is an oversimplification).
It's often used like so:
private val lock = Object()
fun doSomething() {
synchronized(lock) { ... }
}
This means the code ... will only be executed by one thread at a time...
Now this has nothing to do with Android Lifecycle, App Lifecycle, and more specifically, Android Activity Lifecycle.
Your problem is an architecture problem. You have a UI (Activity) that can and will be destroyed by the Android OS at will (or when your users leave your app either explicitly or by performing a different action like turning the screen off).
You also have a block of code that -and I quote- "should not get executed in parallel in my application". Now this is a bit misleading. Do you not want this code to be run multiple times at the same time (in parallel, that is) or do you only want to run this code "once" in your app and never do it again until certain condition is fulfilled?
Depending on which case you need, the solutions may be different, but in all cases, the actual code that needs execution should not be part of an activity, because as we know, Activities are meant to be created and destroyed at all times. This then raises the question of: Where do I put this information that I want to persist for LONGER than what my activity does?
And here you have many options... from using a ViewModel (that can live a bit longer) to using a use-case/interactor/repository/etc. that can store this "information" in a more persistent way, and be able to provide it to the (new) activity when it is restored.
I suggest you spend some time reading about MVVM, Android Jetpack, Android Lifecyle, and, because your block of code appears to be "long work" you execute in a background thread, invest time in learning the basics of Kotlin Coroutines, LiveData and/or Flow/StateFlow, as they will make your modern Android life easier.
when I turn the device and back, each time the current Activity gets ended and a new one starts
This means the data that would let the code/activity decide what to do, should not live in the activity, otherwise it would get lost when the inevitable Activity Destroy/Recreate happens. Think of this: You wouldn't store your car keys inside the car... would you? ;)
This is why ViewModels, Respositories, etc. can help you overcome this. In truth, you may or may not like the extra complexity, code, boiler-plate stuff, etc, that comes with this, but when you're developing an Android app, you have to abide by its idiosyncrasies (and bad decisions sometimes). Try telling an iOS dev that you don't want to use ViewControllers and that you're gonna build your own... they are going to scream at you: "Don't fight the framework!!!!!!!"...
Well, this is similar. Do your best to learn the Android way.

Creating global Runnable?

So, I've implement sync mechanism, that uses Runnable.
The thing with Runnable is, that you have to make sure it's properly created and destroyed in Activity. What happens if you have alot of activities? - Alot of boilerplate code.
Is there a way to create a single instance Runnable for whole application?
Is it okay to initialize it in SomeClass extends Application as its app entry point? If so, how would one solve cases as such: SomeClass.onCreate() will hit even if user receives notification (that would also mean, that sync happens every time user gets a notification - which is terrible).
Why don't you using life cycle aware app component like - LiveData and ViewModel from android app architecture components. This is the best solution with AsyncTask.
With Runnable you don't have any control to stop or resume your execution with activity lifecycle. Because if a Runnable doing task in background it will complete any how and it causes defenitly memory leak.
Another easy solution is you can try using RxJava and RxAndroid, so simple in less code, see this.
And if you still want traditional way you can try this.

Android: Two Activities Simultaneously

After searching for similar questions here on StackOverflow, I've come to the understanding that you cannot run 2 activities simultaneously. Is there any way around this?
I've read about Services and Asynctasks, but I'm still a little bit confused.
I thought Threading/Intents/Handlers would work, but i'm finding that threading is a way to go from one activity to another (please correct me if I'm wrong) and not running two things at once.
Let's say I wanted to combine an android MediaPlayer activity and a video recording activity, while still being able to have the two interact with each other, would it be possible in android? is it possible to have the camera running while having a video play/having a separate activity run within the same application? If so, How?
I found a question here that addresses a similar issue(https://stackoverflow.com/questions/12021518/android-simultaneous-record-and-playback-different-sources), But it is unanswered.
Any suggestions or advice will be greatly appreciated!
Intent ,Handler and Thread are really 3 different things.
An Intent is basically a message to say you did or want something to happen. Depending on the intent, apps or the OS might be listening for it and will react accordingly. So an intend is used to navigate from one activity to another. (For you example : A camera intent can be used a request to capture a picture or video clip through an existing camera app and then returns control back to your application.)
A Thread must be created to execute long running jobs. If you do not explicitly start it in its own thread then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users.
A Handler is very convenient object to communicate between 2 threads (for instance : a background thread need to update the UI. You can use a Handler to post some Runnable from your background thread to the UI thread).
As #krishna has mentioned you can try fragments...

ANR Exception handling

I have an application, where we are providing the Remote UI(which contains all the buttons to control the Media server).
The problem is when we click any of the button, we are executing the corresponding action, which is very long UPNP network operation.
so when we press the buttons continuously , finally the device comes up with ANR Exception and force close the application. I made some research on this ANR Exception and finally found that, we can use Thread or AsyncTask to solve this problem.
But in my application since we are providing so many buttons, when user presses buttons continuously , it may inturn lead to lot of threads created in the application.
Please give me your suggestions on this.
How to overcome this problem?
Thanks
One of the many advantages of using AsyncTask is that it manages the threading (and thread pooling) for you. So if you use AsyncTask, you shouldn't have the problem of creating too many threads.
In addition, if you're concerned with creating too many AsyncTasks, consider putting the tasks in a member variable (such as a Queue or ArrayList) and keeping track of their state. If one is still processing it might not be necessary to start another. Or you can remove tasks whose results are no longer needed.
Just keeping track of the button click in member variable and using One AsyncTask you can perform this long running operation in queue wise.
If possible just avoid multi-threads for these operations.

Android Concurrency issue

I have strictly separated the layers between different parts of my Android application.
At some point of execution I am updating my data from xml service on Internet. That updating takes up about 10 seconds and is done completely in the background - meaning the user interface of an application works fine. However further calls to my class (later - DataManager) which is responsible for data updating (after update has been started but not yet finished) makes my application crash. NullPointerException is thrown with objects which NEVER are null.
So I assume that only one Thread can use my DataManager at one time and calls to DataManager from other threads ends up in exceptions.
I tried various combinations of putting 'synchronized' keywords near sensitive methods but it seems that when update is executing - NOTHING can use ANYTHING from my DataManager.
BTW other classes which are related to DataManager during the execution also seem to hold null objects.
I guess I am just missing some kind of design pattern which is used to deal with concurrency problems and maybe anyone can suggest me something?
I had trouble dealing with using the Apache http client because of threading issues and I think your issue could be similar in that respect. What I ended up doing was setting up a callback scheme. This may or may not work for you, of course.
This may seem a bit Rube Goldberg-like to you, but it worked for me.
I would have my UI thread call my data manager object with a method that spawned a thread to go and acquire the data. The method's return value is an object that would EVENTUALLY have the data in it. I would have my activity extend an interface, something like "DataCallbackInterface", with a method that the thread would call after it acquired the data (i.e. the last line in run()). Since that call will inherently be within another thread, you'll need to use a Handler to run anything useful in your implementation of the DataCallbackInterface method. When that method is called, you will know for a fact that the data is there and not rely on any strange synchronization flags to get it right.

Categories

Resources