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.
Related
So I have this view that moves throughout different views that I have. I tried moving it using a new thread but I got "Can't access View from a different thread than it was created on", so I was like, "whatever just move it to the main thread then". So, I currently have runOnUiThread(this) (The class implements Runnable).
Now, it says:
Skipped x frames! The application may be doing too much work on its main thread.
I googled for a loophole and found that I can use a Handler to do this, which I was able to follow until it was talking about implementing a task. They used a task called PhotoTask and not knowing what it was or where it came from, I just got lost.
So can somebody either explain the Task or tell me another potential way around this?
Code that's causing the error (Note there are more if statements, but they're all the same on the inside as this one:
while (lackees[i].getTileX() < lackees[i].getDestX()
&& lackees[i].getTileY() < lackees[i]
.getDestY()) {
lackees[i].setTileX(lackees[i].getTileX() + 1);
lackees[i].setTileY(lackees[i].getTileY() + 1);
getTileAt(0, lackees[i].getTileX() - 1,
lackees[i].getTileY() - 1).removeView(
lackees[i]);
getTileAt(0, lackees[i].getTileX(),
lackees[i].getTileY()).addView(lackees[i]);
Progress Update #1:
It seems that wait() is better to use then Thread.sleep() but I still get frames lost, just not as many.
Your question is not very clear.
What do you mean by "So I have this view that moves throughout different views that I have".
Handler are mainly used to communicate between 2 threads.
PhotoTask in given link is simply an object/model used to send message from 1 thread to another via Handler.
If you want to update a view, you need to do this in main/UI thread alone. If you want to do some UI update from a separate thread you need to inform the default UI thread handler by passing the operation to be done as a separate runnable instance via runOnUiThread/ view.post/ handler.post.
I can clarify on how to use shared views without using any handler or thread if this is what you need.
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
In my android application the scenario is this -
I have several images stored in the SD card.
Now in my app I have an Image view and I have to update this image view continuously
like a slide show is running. This has to be done by fetching images one by one from SD card and setting them in the same ImageView. Also the interval of image change in ImageView is fixed.
So I have a cursor which stores the information for fetching these images.
Now I am wondering what should be my approach for moving the cursor one by one and fetching images from SD card and setting them in my ImageView.
Should I use Timer Task and Timer or should I go with Handler or something else?
Please help as this is initial point of my app and I want to start in the right direction.
Since you're retrieving large data from the SD card, it might be best to use a thread to retrieve/decode the bitmap.
In this case, a Timer would be useful because it runs on it's own Java thread for scheduled periods of time. However, you have to keep in mind that you can't update a UI element from a non-UI thread. Thus, you'd need a syncing element in place for when the bitmap is fully loaded to finally put the decoded bitmap in to the ImageView. In which case, you would need to use Handler anyway to send message queues to the UI thread.
Thus, I'd probably recommend using a combination of Handler and AsyncTask. Create an AsyncTask class that retrieves and decodes the bitmap in doInBackground(). Update the ImageView in onPostExecute(). Use a Handler to create and execute a new AsyncTask ever Nth milliesecond (whenever you update the view).
One advantage to this is it keeps all image retrieval in one class. You can open the cursor, retrieve, close it. This is safer than keeping a long-running cursor open.
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.
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.