Updating UI In Android - android

I want to Update UI from background thread and if user wants to interact with UI while updating then the UI should not blocked by background thread.
Please Help me out.

This can be done using handlers to post UI updates from background thread. You can refer https://developer.android.com/training/multiple-threads/communicate-ui.html for code sample.

Using this you can update UI from backgorund thread
runOnUiThread()
runOnUiThread(new Runnable() {
#Override
public void run() {
//ui update stuff
}
});

You can use handler to serve this purpose.
A simple example:
Create a class:
class Task implements Runnable {
#Override
public void run() {
for (int i = 0; i <= 20; i++) {
final int value = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
progressBar.setProgress(value);
}
});
}
}
}
Then call it from where you want to update the UI like this:
new Thread(new Task()).start();
Complete Example can be found here.
Or you can also go with different approach. Using runOnUiThread method will also allow you to achieve your expected result.
Example:
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});

Related

Best way handle result from thread on UI

I want to save data to DB in new Thread and after that show toast on the UI.
Method for saving:
public void addToBasket(String text) {
new Thread(() -> {
//emulate save
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//after that I need say ti UI thread - show Toast!
}).start();
}
I call this method:
BasketService.me().addToBasket(result.getContents());
I do now want use AsyncTask for this. Please tell me the best way to implement such tasks
batter to use:
runOnUiThread(new Runnable() {
public void run() {
//Do what ever you want do man
}
});
runOnUiThread() method to manipulate your UserInterface from background threads.
In case of callback from a nonUi thread to Ui thread you can use runOnUiThread()(As specified above) or Handler. Below is a example of using handler.
protected static final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
protected void onSuccessInMainThread(final R result, final Bundle bundle) {
mainThreadHandler.post(new Runnable() {
#Override
public void run() {
callback.onSuccess(result, bundle);
}
});
}
protected void onErrorInMainThread(final Exception error) {
mainThreadHandler.post(new Runnable() {
#Override
public void run() {
callback.onError(error);
}
});
}

Android- Updating UI elements with threading

I have a textview which i want to change with a thread and do it again and again (Like a digital clock). But i'm having problems with setting time between 2 changes. Here, the code:
display1 = (TextView) findViewById(R.id.textView1);
Thread timer2 = new Thread(){
#Override
public void run() {
synchronized (this){
runOnUiThread(new Runnable() {
#Override
public void run() {
int i = 0;
display1.setText("" + i);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
display1.setText("" + (i+1));
}
});
}
}
};
timer2.start();
This sleep(2000); function makes textview invisible for the given time but i want it stand still till the next change. How can i do that?
But i'm having problems with setting time between 2 changes
Do NOT do sleep() on your UI thread. If you want to chain some actions with the delay, split your code into two runnables and the first one should set display1 and then post second runnable with the delay using postDelayed()
EDIT
want one of them to increase 3 per sec, and the other 5 per sec until they reach 1000 for instance
You can make your Runnable post itself until some criteria are met (i.e. time, counter value etc). Just at the end your Runnable check your conditions and if not met, call postDelayed(this, delay); and you are good.
You should use a Handler instead and dispatch your changes to the UI thread.
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
#Override
public void run() {
// Code to be run right away
}
});
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// Code to be run after 2 seconds
}
}, 2000);
Maybe split up what you need to do into separate methods. Here you have a UI method and a sleep method split up. Hope it helps
private void myMethod() {
new Thread() {
#Override
public void run() {
int i = 0;
doWorkOnUI(String.valueOf(i));
pause(2000);
doWorkOnUI(String.valueOf(i++));
}
}.start();
}
private void pause(int pauseTime) {
try {
Thread.sleep(pauseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doWorkOnUI(final String string) {
runOnUiThread(new Runnable() {
#Override
public void run() {
display1.setText(string);
}
});
}

Thread not executing UI comes out saying unfortunately stopped

Where timer is a textview and throws error during runtime and UI comes out saying unfortunately has stopped.Have attached error mess link below.Plz help not understanding where I am going wrong
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.level_twolayout);
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
Timer.setText("Hello");
}
}
});
t1.start();
}
You must update UI from main thread.
Use this code. in place of Timer.setText("Hello");
// verify we are indeed updating UI on main thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// go ahead and update UI
Timer.setText("Hello");
}
});
runOnUiThread is an Activity method. See http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29.
You need to call MyActivityName.this.runOnUiThread() or more simply just runOnUiThread() as "this" will point to the scope of the Runnable you are creating and not your Activity.
Lastly, "Timer" may not be the best name for your TextView.

Updating UI using a Handler freezes my app

I am trying to make a clock, using a TextView :)
Someone here told me that I couldn't use normal threads to change the UI, but Handler or AsyncTask. I managed to get it working a few days ago, but was not a consistent thread.
Now what I want is a consistent thread that is always changing the text of my Textview. I tried using this, but didn't work, any help?
private void startClock() {
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
while (true) {
final long millis = System.currentTimeMillis() - MainActivity.startedAt;
clock.setText("" + millis);
runOnUiThread (new Runnable() {
#Override
public void run() {
clock.setText("" + millis);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}, 2000);
}
you should get rid of:
while(true) {
....
sleep(1000);
...
}
because this get your thread stuck forever. your program should work like this:
private Handler mHandler = new Handler();
#Override
public void onResume() {
super.onResume();
mHandler.removeCallbacks(mUpdateClockTask);
mHandler.postDelayed(mUpdateCLockTask, 100);
}
#Override
public void onPause() {
super.onPause();
mHandler.removeCallbacks(mUpdateClockTask);
}
private Runnable mUpdateClockTask = new Runnable() {
public void run() {
updateClock();
mHandler.postDelayed(mUpdateClockTask, 2000);
}
};
and inside updateClock() you do all your UI updates.
Look here for an example https://stackoverflow.com/a/11140429/808940
Also note that you have a duplicate line in your code:
clock.setText(""+millis);
It appears both in the runOnUiThread and in the main handler, it should only appear in the runOnUiThread runnable

Android timer and NetworkOnMainThreadException

I am using following code to update a list after certain time.
Myactivity {
setTimer() {
Runnable r = new Runnable() {
run() {
if(!isListUpdated) {
update();//n/w operation
} else {
show();//this is a UI operation
listupdated = false;
}
Handler.postDelayed(this,next); //repeat after next
}
new Thread(r).start();
}
}
}
After 2 - 3 iterations it is giving NetworkOnMainThreadException. Can somebody tell what is wrong in this code?
You should not do network operation in Main Thread. Create a separate thread and do nw operation there.
You can use AsyncTask, Service or separate thread . Where you ll do network operation. and update via BroadcastReceiver, Handler or AsyncTask.
Read about AsyncTask here
This exception usually occurs when you try to perform network operations in the main thread. Use an AsyncTask for your network operations.
Consider using runOnUiThread to perform UI operations in Non-UI Thread.
Your code snippet should be something like follows.
Runnable runnable = new Runnable() {
public void run() {
if (!isListUpdated) {
runOnUiThread(new Runnable() {
public void run() {
update(); //n/w operation
}
});
} else {
runOnUiThread(new Runnable() {
public void run() {
show(); //n/w operation
}
});
listupdated = false;
}
handler.postDelayed(runnable, next);
}
};
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
so you need to Use Thread, runOnUiThread, AsyncTask , Handler , or HandlerThread for Updating UI elements from background Thread.
an example using thread and runOnUiThread :
public void myThread(){
Thread th=new Thread() {
#Override
public void run() {
try
{
while(true) {
Current_Activity.this.runOnUiThread( new Runnable() {
#Override
public void run() {
//UPDATE UI FROM HERE
}
});
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
I guess you are using honeycomb version, you better use AsyncTask it will solve your problem.

Categories

Resources