My understanding is that Android instrumented JUnit tests run on their own thread unless annotated with #UiThread or calling Instrumentation.runOnMainSync() or Activity.runOnUiThread(). Now I'm trying to use a CursorLoader to access my app's database and populate a ListView. I also have a test which verifies that the ListView is populated correctly.
My problem is that I need to synchronize three threads: the test thread should wait until the CursorLoader thread finishes and notifies the UI thread to populate the ListView. To create a CursorLoader, I register a LoaderCallbacks with the support LoaderManager and create the instance in onCreateLoader(). Then onLoadFinished() changes the cursor of the ListView's adapter.
Now I need to ensure that my test waits until onLoadFinish() has been called before attempting to access the child views of the ListView. My current idea is to add a waitForData() method to my LoaderCallbacks implementation which the tests can call. However, I'm not sure how to implement this method. Can I simply use a wait() and then notifyAll() in onLoadFinished()? Or do I need to use something more sophisticated like a Semaphore?
Espresso handles this type of synchronization. I have not yet worked with it to figure out the details, but it looks very promising.
Related
I am using sockets and im getting data continuously in background using Asynctask.
I send this data to onProgressUpdate() with publishProgress()and I would like to know if there is a way to get the data from function onProgressUpdate() or send it to another class, because where I do need to use this data is in another class. At least, is this possible?
I have a .java, in this .java I have 2 public classes:
First one is a class where I use this Asynctask in background to get socket info.
In the second public class I use OpenGL and I need to use that data.
Thank you
Sure it's possible. You define the type of the array passed between doInBackground() and onProgressUpdate(). You can just publish the progress and consume it that way.
new AsyncTask<...,MyDataObject,...>() {...}.execute();
Alternatively, you can create a publish-subscribe interface between the thread running dIB() and whatever thread is consuming it.
Not that AsyncTask isn't intended to be used for long-running operations. It's meant to be a relatively quick one-shot. You'll need to consider running your task on a dedicated executor so as not to block the one serial executor that's used by default for all other instances of AsyncTask. E.g.,
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Yo can do this with publishProgress() method and you can call this method from doInBackground() and this method can be called at any time when you need to get your data.
Then get data what you want from params and store it in public variable of Asynctask and access it from another class.
This may be work.
I'm refactoring an app I made some time ago. Back then I was taking my first steps into Android and the easy way to go was to avoid orientation changes, for almost all my CRUD operations I used the AsyncTask class, didn't implement a Content Provider or used Fragments.
Now I have made some changes:
I use Fragments to encapsulate functionality
All accesses to my database are done through a Content Provider
I use CursorLoaders to retrieve my data taking advantage of the content observation and automatic background loading the LoaderFramework brings.
The only problem I have now is that I'm not quite sure how to handle the rest of the CRUD operations (Create,Update, and Delete).
I've found that I can use the AsyncQueryHandler class, but there's not enough information online.
One thing I like the Loader Framework, is that is aware of the Activity or Fragment lifecycle, but what about the AsyncQueryHandler?
What happens to the operations that were started with startDelete, startInsert, startUpdate when the Activity/Fragment undergoes a configuration change? Or when I press the back button? Or worse yet, if the activity is destroyed?
What is the expected behavior of this kind of operations in such cases? Should they be cancelled or should they continue to do their work?
All the operations I've mentioned above are not that complex. For real complex operations I've used Services or IntentServices, but since I don't consider a good idea to run SQLite operations on the main thread I want to use a better solution, but first I need to know how that solution should react to the Activity/Fragment lifecycle events.
Any comments or suggestions would me greatly appreciated.
Thanks.
If you use AsyncQueryHandler you have to take into consideration that this abstract wrapper is created and executes provider operations on the thread that it was started on. If you call this from UI thread the callbacks will be sent to the UI thread. If you call this from another working thread, the callbacks will be sent to that working thread.
This is not bound to the lifecycle of the fragment or the activity, ContentProviders don't have an lifecycle.
The AsyncQueryHandler at an basic level, creates an Message object which is added to the MessageQueue of an single background thread. No matter from which activity/fragment you use the AsyncQueryHandler all the Message objects will end up on the same MessageQueue.
Once the background thread processes an request it will send the response back to the instance of the AsyncQueryHandler from which the request was initially made.
My recommendation is to use the Loaders from Android. These are directly tied to the lifecycle of the activity/fragment. You can have multiple Loaders in a LoaderManager(one LoaderManager per activity/fragment) which allows to do more complex operations. Your activity/fragment will automatically be notified when the content has changed(very useful when you want to combine it with your custom methods for CRUD operations or if you need to use long running services). Another very important feature they have is that they will always reconnect to the last Loader, thus you will avoid re-querying your content.
I recommend you search for some tutorials for implementing Loaders in Android. You can start with these:
Loaders - part 1
Loaders - part 2
Loaders - part 3
Loaders - part 4
Answer for your last comments:
I suggest to use the EventBus library (https://github.com/greenrobot/EventBus) to make the communication between your AsyncTasks/Thread and your other components.
You can start by creating an abstract AsyncTask/Thread and on top of that to make your specific command.
For example:
public abstract class AbstractThread extends Thread {
#Override
public void run() {
super.run();
command();
}
abstract void command();
}
In the abstract class you could make some DB initialization, verification or anything else that might make sense for your application.
public class InserTask extends AbstractThread{
#Override
void command() {
//TODO: Add logic for the insert task
}
}
public class UpdateTask extends AbstractThread{
#Override
void command() {
//TODO: Add logic for the update task
}
}
In these specific classes, just add your logic of the CRUD operation.
To have control over these threads, like when they should be stopped, paused, resumed you could create and ThreadPool manager which controls your threads. You can read more how to achieve this here: Thread Pool
what is meant by asynchronously loading data in activity or fragment in android?
This is my question. I searched everywhere. I'm not getting a generalized definition for this?. I can't get the term mentioned in android developer also.
Can anyone provide me the basic explanation of this term?
Asynchronous in Android mean that you do stuff while the user can interact with the User Interface (UI) : you are not blocking the UI while you are doing long stuff. So the user can still navigate, change activities or fragment and your data is still loading.
For data : you load it, parse it and do whatever you want in a NON-UI Thread (using AsyncTask eg) and then notify the UI, and display what you need to.
You have many possibilities to implement Asynchronous load in Android, and you have many different way to manage your request. I personnaly recommend using Retrofit if you need to use a Web API.
It means that you load your data in a separate thread than the UI thread. You launch your HTTP request for example in another thread and when it finished you notify the UI thread to refresh display.
This mean to load data in separate thread rather than load the data in main thread.Loading data in main thread may cause app to block
The AsyncTask class encapsulates the creation of a background process and the synchronization with the main thread. It also supports reporting progress of the running tasks.
To use AsyncTask you must subclass it. AsyncTask uses generics and varargs. The parameters are the following AsyncTask .
An AsyncTask is started via the execute() method.
The execute() method calls the doInBackground() and the onPostExecute() method.
TypeOfVarArgParams is passed into the doInBackground() method as input, ProgressValue is used for progress information and ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as a parameter.
The doInBackground() method contains the coding instruction which should be performed in a background thread. This method runs automatically in a separate Thread.
The onPostExecute() method synchronizes itself again with the user interface thread and allows it to be updated. This method is called by the framework once the doInBackground() method finishes.
I am looking for the right way of designing my app here.
I have 5 activities and each one calls a separate DB method (update, insert, delete ..etc).
I was wondering, instead of creating 5 asynctask classes, each is a private class belonging to the activity to be called from, is there way I can create one asynctask class so I instantiate its object in all the activities?
In C++, you can pass "an entire method" to be executed so Ican create an assign task and pass a method to it to be executed, but I am not sure I can do that in Java. Or what would be the best practice in your mind?
Thank you
Check the Runnable class.
A Runnable represents a task that can be executed. You need to implement it's run() You can pass an instance of Runnable to your AsyncTask and execute it in it's doInBackground(...) method.
There might be a better way to do this, but this is the only thing that is comming to my mind right now.
I'm not sure if this would fit your bill but I would recommend creating an IntentService, that would automatically and asynchronously queue up your Database/Content-Provider read and writes.
You can write separate read, write and update methods that will be handled in the onHandleIntent method of the IntentService. The Intent service insures that
the database/CP access is done asynchronously
successive database/CP access requests are automatically queued and handled
the Service is stopped/started automatically, no need to manage the lifecycle
the database/CP read/write is done even if the app goes into the background
For ListView/Adapter access, consider using loaders
I have an activity that runs a query on a Sqlite DB, gets a Cursor, creates a CustomCursorAdapter with that Cursor, and attaches it to the ListView in the activity. It looks like this:
SQLiteDatabase db=new StuffHelper(this).getWritableDatabase();
Cursor c1=db.query(StuffHelper.TABLE,
new String[]{StuffHelper._ID},
StuffHelper.SIZE+">=?",
new String[]{"64"},
null,
null,
null);
startManagingCursor(c1);
StuffAdapter a1 = new StuffAdapter(this, c1);
ListView ll1 = (ListView) findViewById(R.id.ll1);
ll1.setAdapter(a1);
Is this current setup a problem in terms of ANR? When using cursors, how can I tell android to run all the Sqlite stuff on a background thread?
You didn't give much context of when this code is run, but I'll bite anyway...
Yes, it does run the risk of an ANR. It also runs the risk of various other lifecycle problems. Since setListAdapter() needs to be called before various other thing that you'd normally do in onCreate() you probably want to offload the database access to a separate thread (like an AsyncTask) that can be called/cached/managed as needed. AsyncTask gives you a UI-based callback before the thread starts and a UI-based callback when the thread ends. The ListAdapter can be created and assigned without any references to a Cursor (and I'd suggest you fix that asap... there doesn't seem to be a good reason why you're using a custom list adapter, you should be managing your database access better instead).
Managing this task over activity teardown and rebuilding (think changing orientation...) is an entirely different ball of wax and has been covered ad nauseam on SO.
Please separate your UI from background tasks. Write the cursor portion in background and in forground you can show any UI or progress dialog. Use AsyncTask for this
AsyncTask class has following methods
1. doInBackground: Code performing long running operation goes in this method. When onClick method is executed on click of button, it calls execute method which accepts parameters and automatically calls doInBackground method with the parameters passed.
2. onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
3. onPreExecute: This method is called before doInBackground method is called.
4. onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.
How to use AsyncTask
Thanks
Deepak