I have an AsyncTask called from Activity1 and Activity2 that is visible now. From Activity2 I am making some changes in the running AsyncTask and AsyncTask must requery cursor in my Activity2.
How do I verify that Activity2 is visible and requery cursor within it from AsyncTask?
I am a little confused -> you want to requery a cursor, that is not in your AsyncTask, but in your Activity? Don't you use AsyncTasks, exactly, to do DB Queries in separate Thread? So why would you like to do that? On the subject of how to (try to) detect if your activity is visible, there's already an answer
EDIT:
You should have defined the AsyncTask as private class to an Activity (I assume you did it like that for Activity1). All methods in AsyncTask, except doInBackground() are executed on the UI Thread of the Activity you've defined the task in.
You don't have to call directly onProgressUpdate(), instead you have to use publishProgress(), but I think you cannot call it from your Activity2.
I am not sure what exactly you're trying to achieve, but maybe you should consider looking at Handlers.
Related
Say I have main activity that contains a list (never mind if it is a ListView or RecyclerView). Each time the activity is created it has in its onResume method a query for data from parse. The thing is the parse query I use calls findInBackground method so my list in main activity is always zero since by the the time the activity is constructed the query hasn't finish yet. when I use find (and not find in background) I see in android studio logcat a sentence like the follwoing : "to many operation on main thread".
What do u think I should do?
Thank u in advance
Expansive operations like this should be done on a seperate thread in the background, so the main (animation) thread will not be blocked, causing your app to lag. The findInBackground() method will do the same as find(), but on a different thread 'in the background'. When the job is done, it will call the FindCallback and pass the result so you can update your list.
Untill this is done you could show a intermediate ProgressBar in front of your empty list to indicate that the data is loading.
How i can know when AsynsTask is ready from Activity? I can not write my code in a separate class, because i use ListView, and fill him. How i can do that without Thread.sleep ?
You can use the onPreExecute and onPostExecute methods of AysncTask to update your UI i.e Activity. Because this methods directly run on main thread
I have activity use AsyncTask to open cursor than spawns children AsyncTask to render items read with cursor.
Activity executes on cursor AsyncTask but not see children AsyncTask for items.
How to cancel all running AsyncTask tasks (including nested) for specified Activity?
How to cancel all running children AsyncTask tasks for specified AsyncTask (if it possible at all)?
I want to stop all tasks on new command from interface to not corrupt views.
There's no manager for the AsyncTask you execute.
You'll have to keep track of all the new instances of the AsyncTasks you've created and close them with cancel(boolean mayInterruptIfRunning) method.
Pay attention that canceling the Task won't stop it in the middle. You'll have to check in your doInBackground - isCanceled()
If your AsyncTask are running loops, then you can check for a common flag (maybe an attribute of some singleton, like the Application class itself, or your activity). As soon as this flag becomes true, then your Tasks will exit the loop
Question arising from my first attempt at using an Async object.
I have a main activity in which some TextViews have been created programmatically and added to a LinearLayout. Also a button, when this is clicked, an AsyncTask object is instantiated and results are obtained in the doInBackGround method. How should the result strings be transferred to the TextViews?
a) by calling the SetText methods of these TextViews from the onPostExecute method,
b) using intents and an onActivityResult method in the main activity
c) some other way (a clue would be nice!)
Thanks!
I would go for the AsyncTask option. I'm guessing that as you already have one in place, the obtaining results part that happens when you click the button takes time, so it's good design to have that in the doInBackground method of the AsyncTask.
Then you can call each TextView's setText(...) method in the onPostExecute method in your AsyncTask. Or, it's more suitable, you can update each view as you get the result by using the publishProgress(...) and onProgressUpdate(...) methods (see the AsyncTask documentation) during the background calculations, instead of having to wait until the end.
Just bear in mind that you can only call setText(...) from the onPreExecute, onProgressUpdate and onPostExecute methods, as (at least it seems this way from your explanation) the views have been created on the UI thread, so they can only be modified from that same thread, which those methods run on.
When using an AsyncTask, you can use the doInBackground method for processing, and the onPostExecute to update any UI changes. So, if you need to use an AsyncTask, I'd go for option A.
Make the TextViews private and define them in doInBackground, then you can just call the setText method in onPostExecute or as the last thing in doInBackground, but i would recommend onPostExecute.
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