Communicate between UI and background thread - android

Its for the first time I'm making a fairly large app and there are lots of sections in it.
I want to keep UI and background processes in different classes to avoid confusion. However, how do i communicate among them in best possible way. I've come across few approaches till now:
Declaring background thread in different class and defined its onPostExecute() method in UI thread.
new SetupDefaultFeeds(context) {
#Override
protected void onPostExecute(List<Feed> result) {
default_feeds = result;
for (Feed t : result) {
String log = t.toString();
Log.d("DEFAULT feed", log);
}
menu_btn[0].performClick();
}
}.execute();
Signalling using a flag variable between background and UI thread.
Thread and handler.
Are there any other ways and what is the best possible way. Thanks !

Passing messages through a Handler is usually the most "Android-ish" way to do this. Trying to do all communication through flag variables is most likely going to be quite a headache.
Edit: Android itself doesn't provide a way for you to link the two classes together, you need to do that by hand. One way which works quite well is to create an interface for your communication and have either the UI class or background thread implement it. Then, when creating the class, you can pass a reference to the other object and communicate through the interface.
However, if you want to completely decouple the two classes, you might want to use a BroadcastReceiver instead and use it to send messages between the UI and background thread.

Related

Android: Put all code on a background thread

Lets say i'm developing a mobile application. As we know, by default, most of the code is going to run on the UI thread.
I want my application to run as smoothly as possible for my users, so i make sure that I am using async/await in all possible places.
On slower android devices, I am still having issues with Logcat telling me that I am skipping frames. So my next thought is to make sure that everything that can be done on a background thread, is put on a background thread. So besides work that has to be done on the UI thread, i put all of my code inside tasks on background threads.
My question is, Can I theoretically put too much code onto background threads, where I am actually making my application slower due to having to move between background threads and the UI thread too much?
You can do that quickly and can still controllable using Observable.
Observable.just("")
.observeOn(AndroidSchedulers.mainThread())
.flatMap { //do UI here }
.observeOn(Schedulers.io())
.doOnNext{ //do Async here }
.subscribe()
You need to use for background execution. Use AsyncTask.
public class SyncDatabase extends AsyncTask<List<ProductModel>, Void, Integer> {
#Override
protected Integer doInBackground(List<ProductModel>[] lists) {
return YOUR_INT;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Integer row) {
super.onPostExecute(row);
// This is mainThread
//you can do what ever you want example: textView.settext(row+"");
}
}
Now you call from main thread
new SyncDatabase().execute(YOUR_GIVEN_LIST);
Yes you can put lots of job in background thread. You can use android threadpool system for group by group thread execution
You can do this if you are confident enough to handle all the thread communication efficiently by yourself. I would suggest using react approach. There are different react libraries available now for Android.
In reactive systems, A full job is broken into several parts. Different workers called Actors perform a different part of the full job and when finishes forward the job to next worker. Channels are used to send and receive messages between workers.

Using a Thread to run Code and update UI Android

How do I use a thread to run some code continuously whilst an Apps running, using the information it gives to periodically update the UI of the App.
Specifically the thread would run some code that searches through a text file in order to find co-ordinates which would then be plotted over a PNG on the UI. This would update automatically say every second maybe every half second, and would clear the image then redraw the points.
How do i first of all set up the thread then second of all send information from the thread back to the UI and have it update?
Any example code would be great or any information you've come across that gives example code. I'm not trying to do it the best way at the moment, just trying to hack it together, so if you know easy and quick (but awful) ways of doing this don't feel afraid to share.
This may help u...
//on create
Thread currentThread = new Thread(this);
currentThread.start();
after on create
public void run() {
try {
Thread.sleep(4000);
threadHandler.sendEmptyMessage(0);
} catch (InterruptedException e) {
//don't forget to deal with the Exception !!!!!
}
}
private Handler threadHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Intent in = new Intent(getApplicationContext(),****.class);
startActivity(in);
}
};
This is a very common scenario and its far boyend the scope of a simple answer to your question.
Here are two usefull links:
http://developer.android.com/guide/components/processes-and-threads.html
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html
And there are a lot more.
Here are two different approaches for you as starting point:
Update gui from your thread, only needs syncronzation with the UI thread. Pass your Activity into your thread, it provides the method: runOnUiThread
Define an interface to provide callbacks, let the calling ui class (activity) implement your interface and register it as listener to your thread. Then you can call the callback, when ever you want. Don't for to syncronize
Try to use service(or IntentService - http://developer.android.com/guide/components/services.html) for background work and BroadcastReceiver to update the UI thread from the service.
Use the AsyncTask class (instead of Runnable). It has a method called onProgressUpdate which can affect the UI (it's invoked in the UI thread).

Implementing a cyclic executive in android?

I am writing an android app and I need to be able to do certain things periodically/continuously. I am coming from a C/C++ embedded firmware background and this new-fangled way of doing things is going to take some getting used to. It seems that there is no such thing as a "main loop" in Android, that everything is event-driven... I also understand that by default all code you write operates on the GUI thread, and I should probably make a new thread to execute the equivalent of a "main loop"...
So far what I have is an implementation of the AsyncTask class who's "doInBackground" method contains an infinite loop (my main loop), I create an instance of this class and run it immediately when my app starts. The problem I am having is in the interaction between this thread and the user interface... when something occurs in my main loop thread and I want to update the GUI understand that I must call "publishProgress", which is executed on the GUI thread. There are a few problems with this, primarily that many things I have tried to do in this "onProgressUpdate" method do not work, or do not occur in a predictable amount of time.
My question, is there a better way to accomplish what I am trying to do? In general, what do most people do when they have code that they want to run periodically and/or continuously while their application is running, code that must interact with the user interface in a timely manner (by timely I mean with zero delay).
Thank you.
public class MainLoopThread extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
while(true)
{
//Do stuff
//Update GUI
publishProgress();
}
}
protected void onProgressUpdate(Void...voids)
{
//Update GUI
}
}
It is unclear what you are trying to do, however just let me say using AsyncTask in this way may have negative consequences.
AsyncTask internally uses a thread pool pattern for running the stuff from doInBackground(). On Android OS before 1.6 and starting from 3.0 the pool size is just 1, meaning no parallel computations for a bunch of AsyncTasks. More details on this here.
So, this may result that only this current AsyncTask is running, while others even if started will have to wait untill the current one is done.
Depending on your needs for things to be done periodically Android exposes:
AlarmManager
Handler - it allows to post a runnable on UI thread with a delay or periodically
Timer + Activity.runOnUiThread(Runnable action) inside of TimerTask
UPDATE: basing on your comments it looks like you need a Service, that starts a thread that periodically sends broadcasts with the data for UI. Then your UI (Activity) registers broadcast receivers to catch those broadcasts, extract the data and use for UI updates.
So your saying that onProgessUpdate() isn't working? That seems weird because it should.
Another option that you have is just to make a Thread that loops.
The trick is that if you want to update the UI thread you will have to make a call to view.post() and give it a runnable that will actually perform the update. The idea here is that you must schedule an update on the UI thread, you can't just take it and say NOW!

Pattern for reusing Android AsnycTask over several Activities?

I have several Activity subclasses in my project, each calling a SOAP based web service, processing and displaying the results. The SOAP serialization, the call handling and the parsing of result into various POJO objects is encapsulated in the MyWebService class. This class executes the actual web service call(s) via an AsyncTask.
For being able to pass back the results to the calling Activity subclass, I figured I enforce that all these activities should implement a WebServiceResultProcessor interface, defining a single function (processWebServiceResults) acting as a callback for the AsyncTask, called from onPostExecute.
I also want to display a ProgressDialog during the web service call. And here comes my question. For being able to display the ProgressDialog (either from MyWebService or it's AsyncTask), I need to pass a reference to the caller Activity's Context. And for being able to execute the callback function from the AsyncTask, I also need to pass the same object reference, but this time as a WebServiceResultProcessor. This seems to me a code smell, passing the same object twice, but can't see any way around that. Instead of interfacing, I could create a new base class, extending the Activity class and enforce inheritance from the extension class, but that would mean I'd exclude ListActivity and the likes from using this MyWebService class.
Is there a better way to do this?
+1, a nice question!
This is not a direct answer on your question. However let me say I think AsyncTask is not a right choice for such stuff. I think so because in this case AsyncTask holds a reference to an Activity (via ProgressDialog instance or the callbacks to be called from onPostExecute()).
Just imagine: in Android the OS may kill the Activity before AsyncTask executes its doInBackground(). This is, of course, some sort of a corner case, but it isn't impossible. Consider a scenario: user gets an incoming call, your activity becomes invisible, the OS needs some more RAM and thus it decides to kill your activity. A memory leak case, at least.
I don't know why Google literally hides the info on how UI should be properly separated from background tasks. Yes, they say "use a Service". But it is not a trivial undertaking. It's a pity Google provides nice guides to almost every development topic, but not on this one. Nevertheless I can suggest to check the "Google I/O 2010 - Android REST client applications" presentation for inspiration. Looks like they gave a key on how such things should be done in Android.
You may have a look into this blog article (part 1 and part 2), which implements a web service with AsyncTaskLoader and the same web service with a Service component. Furthermore it shows the differences between both approaches and there are also interesting comments to the article.
Despite Arhimed's warning, I ended up using AsyncTask, as it still fits my purposes. I just make sure that all Activities calling web services, upon their onDestroy(), send a cancel() to the invoked AsyncTask. The AsyncTask implementation itself gracefully handles the cancel request by checking isCancelled() everywhere where necessary.
As for the original question, I must have had a lapse - the solution is really simple. I pass the Activity subclass instance as an Object to the AsyncTask, and cast it to either Context or to WebServiceResultProcessor, as necessary. Fragments showing how it works:
if (callerActivity instanceof Context) {
ProgressDialog dialog = new ProgressDialog((Context)callerActivity);
}
...
if (callerActivity instanceof WebServiceResultProcessor) {
((WebServiceResultProcessor)callerActivity).processWebServiceResults(soapObject);
}

Asynchronous view manipulation android

I have a little problem I spend a lot of time now. I hope you can help me.
Well, I have an activity witch loads content out of data base in background. It returns asynchrony and modifies my data model. Now I'm looking for a good way to inform the controller to update view. I use the notifyDataChanged method but I got an exception.
Android do not allow to modify a view from another thread. In my opinion this is a basic functionality. So there has to be a way to implement such a functionality.
Can you give me an hint.
I also watch the content observer class. But I don't think that the right one.
Thanks
Please provide some code snippets from your Activity. If you are using AsynkTask which is the best way to do background processing on data, you should use the onPostExecute() method to update your UI, because doInBackground() runs on a background thread, not on the UIThread.
A workaround would be to declare a Handler in your Activity and post a new Runnable in that Handler when you want to acccess the UI, something like this:
mHandler.post(new Runnable() {
#Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
But this is somehow a "hack" and I wouldn't recommend using this. The best way would be to use the AsyncTask.

Categories

Resources