I have an Android app where I would like to display a "Processing..." message at the start of quite a bit of heavy duty number crunching, then display "Finished" when the processing is completed. I try something like this:
TextView T = (TextView)findViewById(R.id.TheStatusView);
T.setText("Running");
T.invalidate();
// lots of number crunching
T.setText("Completed");
As some of you might have guessed by now, the "Running" message never appears, since the application is too busy with the number crunching to get around to redrawing the TextView.
In ASP.NET, I would do something like:
T.Text = "Running";
T.Refresh();
Application.DoEvents();
and the text would be refreshed.
Is there an equivalent in Android, or am I pretty much stuck?
For those of you who are playing at home and looking to do the same thing, here's what I did:
TextView T = (TextView)findViewById(R.id.statusTextView);
new Thread(new Runnable() {
public void run() {
T.post(new Runnable() {
public void run() {
T.setText("Processing Part 1");
}
});
DoTheHardcoreProcessing_Part1();
T.post(new Runnable() {
public void run() {
T.setText("Processing Part 2");
}
});
DoTheHardcoreProcessing_Part2();
T.post(new Runnable() {
public void run() {
T.setText("Finished");
}
});
}
}).start();
This will, in order:
(1) display "Processing Part 1"
(2) execute the code in DoTheHardcoreProcessing_Part1()
(3) display "Processing Part 2"
(4) execute the code in DoTheHardcoreProcessing_Part2()
(5) display "Finished"
Related
So I'm attempting to create background task that needs to be run every hour in an Android app. Its a rather heavy task that takes around 5 - 10 minutes to finish, and right now it runs on the UI thread which of course isn't good, because it hangs the whole application. I've attempted the following in my MainActivity onCreate:
new Thread(new Runnable() {
private Handler HeavyTaskHandler = new Handler(Looper.getMainLooper());
public void run(){
final TextView updatedTxt = findViewById(R.id.txt);
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
HeavyTaskHandler.postDelayed(this, HeavyTaskCycle);
}
}).start();
I have two issues with the above
It works fine the first time, and the task is performed in the background well without hanging the UI thread. However, after this first time and the next time(s) it is run, the UI thread hangs again when it is run. What am I missing?
Notice that before the HeavyTask() method is called i try to set a TextViews text to "Performing cleanup.." .. This never shows, only the "Done.." which happens after the HeavyTask() method is done. How can i ensure that the message also appears before?
I ended up doing the following from MainActivity which doesn't hang the application
private void CreateCleanUpThread()
{
CleanUpThread = new Thread(new Runnable() {
public void run(){
try {
while(true) {
performingCleanup = true;
final TextView updatedTxt = findViewById(R.id.updated_txt);
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing database history cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
performingCleanup = false;
Thread.sleep(CleanUpCycle); // 1 hour wait time
}
} catch(Exception ex) {
System.out.println("Error in CreateCleanUpThread : " + ex.getMessage());
}
}
});
}
// onCreate in MainActivity
...
CleanUpThread.start();
Certainly not the best way, but it works and will do for now. Should be moved to a service instead i think.
I have made an android app, which has two TextViews. When I change the text using setText() then the app stops.
I have read other answers on StackOverflow and have implemented them in my program, but the problem still persists.
Here is my onCreate() code:
TextView ec, vc;
Thread t;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ec = (TextView) findViewById(R.id.ce);
vc = (TextView) findViewById(R.id.cv);
t = new Thread(new Runnable() {#Override public void run() {loop();}});
t.start();
}
Here is my loop() code:
public void loop()
{
try{Thread.sleep(7000);}catch(Exception e){}
ec.setText("");
vc.setText("");
try{Thread.sleep(53000);}catch(Exception e){}
t.stop();
}
I want to empty the text of both the TextViews after 7 seconds.
But when I run my app, after 7 seconds, it stops.
Other answers on StackOverflow say that I should put setContentView(R.layout.activity_main); before I initiate the ec and vc variables. It is already there, but still the app stops.
Please help me.
You can use the View.postDelayed method to run a Runnable on the UIThread after a certain time.
UI Elements can only be changed from the UI (Main) thread, therefore it breaks down. Try using:
activity.runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
}
});
But you'll make the UI thread sleep, which means it'll freeze up any way. So, bad practice.
try that
public void loop()
{
try{Thread.sleep(7000);}catch(Exception e){}
activity.runOnUiThread(new Runnable() {
public void run() {
ec.setText("");
vc.setText("");
}
});
try{Thread.sleep(53000);}catch(Exception e){}
t.stop();
}
public void upload_prescription()
{
dialog = ProgressDialog.show(MainActivity.this, "","Uploading file...", true);
new Thread(new Runnable()
{
public void run()
{
runOnUiThread(new Runnable()
{
public void run()
{
// option1 upload_image.uploadFile(uploadFilePath);
}
}
);
//option2 upload_image.uploadFile(uploadFilePath);
deleteImageFromGallery(delete_image_id + "");
}
}
).start();
}
Hey i tried above code to upload image onto server.it runs well if i use the option 2 mentioned on the code. but if i put the code on the option 2.it gives me this error.
android.os.NetworkOnMainThreadException.
i think option 2 is better because it give a separate thread to complete the though it does not work properly
I'm a noob to Android and I am trying to cycle text from an arrayList of strings and display them in an textswitcher. I want the text to change every two seconds. i used this SO question as my guide and have no problem switching the text with a button. However, when I try to cycle the text with a for loop with a 2 second delay it only shows the first text from the arrayList. How can I make the loop continuously execute with a pause? Any help is greatly appreciated.
My Code;
private void updateCounter()
{
try{
for (int i=0; i< CoinShowReader.tickercontent.size(); i++){
mHandler.postDelayed(new Runnable() {
public void run() {
m_switcher.setText((CoinShowReader.tickercontent.get(CoinShowReader.m_counter)));
CoinShowReader.m_counter++;
}
}, 2000);
}
}catch(Exception e){
e.printStackTrace();
}
}
remove the loop, you don't need it, just schedule anther runnable inside the handler like this:
void updateTextView(){
m_switcher.setText((CoinShowReader.tickercontent.get(CoinShowReader.m_counter)));
CoinShowReader.m_counter++;
mHandler.postDelayed(new Runnable() {
public void run() {
updateTextView();
} } ,2000); }
}
that way every call to updateTextView() schedule the next call and so on ...
Note: don't forget to insert trigger to stop that behavior because it's infinity
I want to change the color of a text after every few seconds. I tried generating a random number and using it for setting the color of the text view object in a loop. But the app is not responding. Can anybody help me with this please?
Try running the color-cycling part of your code in a separate thread. For example
Thread thread = new Thread( new Runnable() {
public void run() {
while(true) {
int number = // generate random number ;
runOnUiThread( new Runnable() {
public void run() {
TextView text = // get your TextView ;
text.setTextColor(number);
{
{
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {}
}
}
}
thread.start();
You will need to run the code that actually changes the TextView via the runOnUiThread because Android does not allow other threads to modify parts of an Activity.
You could use a Handler with .postDelayed() and set it up to have a recursive structure, so each time through it will change the color and then post the next runnable to fire off a few seconds later.