I'm using Loaders to get a JSON from server...
everything are working...
Now I need put all this values in many TextViews...
When onLoadFinished is called, I'm using:
miTextView1.setText(value1);
miTextView2.setText(value2);
//and so on...
Should I use Asynctask to fill all these TextViews?
I've used AsyncTask for things like this before, with good results. You can set your TextViews with default text like "Pending . . ." (bonus points for figuring out some sort of text animation) and then update them in onPostExecute once you have the data. See Tony the Pony's SO answer here for the basic code pattern.
AsyncTask is used to run short term background tasks.
UI can not update with AsyncTask.
You need to do it with Handler in Android.
Related
I'm developing a custom ListView, which uses a custom ArrayAdapter and custom elements.
Actually I'm displaying a list of tweets.
I want to display for every tweet the time elapsed from the creation, exactly like twitter.
I wrote a timer that calls a method on every list element. This method calculate the elapsed time and set it on a TextView on the element with setText().
Problem is that I can't get the list update. The values change only when I add a new element or manually scroll the list.
If you need code ask freely.
EDIT:
The answer of Nick Caballero is correct, but it wasn't working.
I have already tried that code. The problem was in the timer and in a try catch with a generic Exception.
The timer was trowing a CalledFromWrongThreadException. The solution was to use a runOnUiThread for its operations.
Calling notifyDataSetChanged does additional operations that are not necessary here. Updating the view with the time elapsed relative to the timestamp of the data does not imply a change in the data.
See https://stackoverflow.com/a/2679284/724068 for how to loop through the visible views in the list. You can then extract the view containing the time elapsed and update accordingly. Since you have to run this every so often to keep the UI up-to-date, you will have to use a Runnable, posting to the main Looper every second.
Also see https://stackoverflow.com/a/9987616/724068.
You might want to try calling invalidate() on the control once its updated. Code would be helpful though.
Is there a workaround for how long a TextView takes to set its text? I am trying to set a very long string and it ends up blocking the UI thread for a good 2-3 seconds because of that. Since I can't access the TextView from a different thread, I'm completely stumped.
Edit:
Currently, I build up the string inside an AsyncTask doInBackground(), and only call TextView.setText() within the onPostExecute(which is running on the uiThread) The TextView is placed within a ScrollView
You shouldn't have a problem loading even a couple of screens worth of information. If the string is super long, you might consider lazy loading the content in sections.
Since I can't access the TextView from a different thread,
You can use a different Thread and still access your TextView. Without knowing your code its hard to give a good example but you can use runOnUiThread
or
you could use an AsyncTask. Doing it this way, you can do whatever you need to in doInBackground() and set the text in onPostExecute()
Although, I'm not sure how long your string is to take several seconds to load. If you are doing a lot of work to get the string put together then I would suggest using AsyncTask
I have a scenario where i have to do following task:
1. populate a list-view.
2. perform database operation which is very time consuming task.
3. database processing/operation time is sometime unpredictable.
I have used listView using holder pattern, now it is working faster than earlier but still taking significant time. What else i can do to improve the performance.
I have an idea but i am afraid whether it will be good to implement or not. Idea is to put the database operation in AsyncTask and update my listview there only.
But i am afraid of doing so is because my listview is totally dependent on database result. So i can display something on Listview only when i am done with DB operation
Please suggest is using Async task will be good approach and please suggest any other idea.
Using the Holder approach is good. Use that in your adapters always. Make sure you are reusing the convert views as well.
Using an AsyncTask is the best option. But you don't have to wait for the entire operation to complete. Read up on how AsyncTask works. Use the publishProgress() method in your doInBackground() of the AsyncTask to give batches of data to your list.
For example, if you have to process 100 rows, process 10, then do a publishProgress() which will update the list with those 10 rows. When you process the next batch, update the list with publishProgress() again.
The endless adapter that I've used in my code, doesn't stop expecting data even if I am out of it. Thus the throbbing symbol, which is the loading symbol here, keeps on circling expecting some data.
How do I stop it? How do I make the endless adapter know that I'm out of data?
Also, I would like to tweak the adapter so that it can use multiple lists. Is it possible? By multiple lists, I mean list embedded inside another list. If yes, is there an example or any ideas as to how to do it?
How do I make the endless adapter know that I'm out of data?
Quoting the documentation:
Your EndlessAdapter subclass also needs to implement cacheInBackground(). This method will be called from a background thread, and it needs to download more data that will eventually be added to the ListAdapter you used in the constructor. While the demo application simply sleeps for 10 seconds, a real application might make a Web service call or otherwise load in more data.
This method returns a boolean, which needs to be true if there is more data yet to be fetched, false otherwise.
Since this method is called on a background thread, you do not need to fork your own thread. However, at the same time, do not try to update the UI directly.
If you expected to be able to retrieve data, but failed (e.g., network error), that is fine. However, you should then return false, indicating that you have no more data.
Also, I would like to tweak the adapter so that it can use multiple lists. Is it possible? By multiple lists, I mean list embedded inside another list.
No. Android does not support the notion of lists inside of lists. You are welcome to take a look at my MergeAdapter (if you really mean that you wish to concatenate multiple lists together) or Android's ExpandableListView (if your lists-in-lists is really some sort of shallow tree structure).
It is possible to use different data for your own Adapter this data can be of any type such as
ArrayList<HashMap/HashSet<?,List<?>>> it is your own business how you will use it within your getView(...) method. You can implement a poller service which will update your Adapter with data accordingly and setAdapter() after. If there's no data just idle...
hope this helps abit.
I like that my GUI appears immediately when the user starts the app.
Then some data (text, pictures) gets loaded in the background (like YouTube app).
The ListView and Gallery gets updated automatically with this new data.
I initiate my ListView, start a Thread and load the data... and then the ListView does not get updated!
Several people told me I should use notifyDataSetChanged().
But I cannot place this command in my Thread (just unknown).
Any ideas?
I have this same problem... and I got excited when I came across this question. But no answer? :-(
After, letting the problem sit for about two weeks I found the solution here:
Long story short:
Quote from above link:
We must use a Handler object because
we cannot update most UI objects while
in a separate thread. When we send a
message to the Handler it will get
saved into a queue and get executed by
the UI thread as soon as possible.
Once you check out the code you see get what the author is saying.
NOTE: Even with a handler, Android may not let you update a view object from the thread's run() method.
I got this error:
05-31 02:12:17.064: ERROR/AndroidRuntime(881):
android.view.ViewRoot$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
To get around it I updated an array of data in my run() method and used that array to update the view in the handler's handleMessage() method.
I hope this helps others out there.
You may use the slowAdapter to refresh the View:
SlowAdapter slowAdapter = new SlowAdapter(this);
list.setAdapter(slowAdapter);
slowAdapter.notifyDataSetChanged();
Just found it myself while reading this thread and trying around.
Short: AsyncTask's method onProgressUpdate can touch the view: http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)
Background: I needed to call requery on my cursor so a ListView kept being updated while the task fills the database. The requery call made in doInBackground failed with the mentioned CalledFromWrongThreadException but same code in onProgressUpdate works.