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
Related
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.
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.
i have this code
TextView B = (TextView)findViewById(R.id.txtMSG);
B.setText("Loading...");
Call_My_Func();
B.setText("");
my function Call_My_Func() work for 1 minute, but i can see the message "Loading..."
is there in java for android something like Application.DoEvent() like i use in C# ?
You are not seeing the message because you're blocking the UI thread with that long running call (as you seem to know based on your DoEvent comment).
An easy way to move long running operations into another thread is Androids AsyncTask.
Well, to give you a bit of history on this project - I'm parsing a string that's about 100k in a child thread, and returning the Spanned object from Html.fromHtml().
The issue is when it returns to the main thread - when trying to setText using the Spanned that was just created in another thread, it takes quite a long time processing it from a Spanned object into a displayable format (setText).
I would normally process this in the child thread, but unfortunately, since this is related to the UI, I can't - has to be on the main thread. So, my question is whether there is a way to process the Spanned into something easily interpreted by the setText, so that it doesn't spend a lot of time on the main thread processing it after the child thread has finished.
testQuestionsExplanations.setText(spannedExplanationsObj);
My biggest issue is that it locks the main thread down doing this.
I found a work around for my problem.
Instead of sending the whole Spanned object and getting it processed onto the TextView all at once, I'm sending smaller pieces, and just appending them to the TextView.
This way my ProgressDialog doesn't lock up completely - it's jerky, but it's better than not moving at all.
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.