Call adapter.notifyDataSetChanged() from another thread - java

I want to call adapter.notifyDataSetChanged() from another thread. I read that I should use an AsyncTask and do the adapter.notifyDataSetChanged() in post execute.
I must execute the AsyncTask every 5 seconds only on the current activity (might be parent or child activity) because only one activity can do the asynctask at the same time.
Should I create a TimerTask which executes the AsyncTask every 5 seconds, stop it when I start another activity and start it back in onResume ?
Here is my code for the thread which updates the ListView of the current Activity.
private void runEventHandler() {
new Thread() {
public void run() {
while (true) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Now I must be able to update the child activities' ListViews when a new User is added.

one possible way is that you create a flag in both activity to control your threads to be run ( the following codes are not runable just example to understand what you can do):
Activity A
{
public static boolean stopThread = false;
#Override
public void onResume()
{
super.onResume();
// put your code here...
stopThread =false;
runEventHandler();
}
private void runEventHandler() {
new Thread() {
public void run() {
while (A.stopThread != false) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
#Override
protected void onStop(){
super.onStop();
stopThread =true;
}
}
Activity B
{
public static boolean stopThread = false;
#Override
public void onResume()
{
super.onResume();
// put your code here...
stopThread =false;
runEventHandler();
}
private void runEventHandler() {
new Thread() {
public void run() {
while (B.stopThread != false) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
#Override
protected void onStop(){
super.onStop();
stopThread =true;
}
}
also you can use onPause() instead of onStop(). depends on your program concept.

You should a timertask like in link below : https://examples.javacodegeeks.com/android/core/activity/android-timertask-example/
the code to post any change on UIThread if you are in a different thread like doInBackground of AsyncTask:
runOnUiThread(new Runnable() {
#Override
public void run() {
// Here you can set your Ui Components
}
});

Related

SwipeRefreshLayout animation frozen

I am trying to use swipe refresh layout to update some data.
All works fine but a small bug that I can't seem to solve
When I pull to refresh, the animation gets frozen.
I have implemented it this way:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRefreshLayout.setRefreshing(false);
}
});
and also tried this:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
myRefreshLayout.post(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
});
}
});
but the animation remains frozen until the everything is done, and then it just vanishes (because it hits the setRefreshing(false))
After searching a little, I thought it could be the UI that is waiting for the stuff to finish, so I tried to implement it this way:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Thread(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
});
}
});
}
What happens in this case is that the refresh indicator never vanishes, so I guess it is not calling the runOnUiThread
I tried the same thing with the main looper (handler) instead of the runOnUiThread with the same effect.
Is there any neat way of implementing this?
Am I missing some detail?
I tried the steps described above and I also looked on Stack Overflow for similar issues to no avail.
Thanks!
It's right to do refreshing on background thread,and setRefreshing(false) on main thread. The problem is you forgot to call start() after new thread.
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Thread(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
}).start();// start the thread here
}
});
}

Auto updating UI with a different thread

I have an Android App which constantly auto updating a list of data from the App's SQLite which an ArrayAdapter is used for handling the data, So for this I've made another thread or handler from the onCreate method of the Acitivity, and inside it's code there's a continuous loop for updating then waiting (or sleeping the thread for a moment, ex/ 10 sec), There are two problems involved:
1- Only the UI thread can touch it's views (though I only touched ArrayAdapter if it counts as a View).
2- Once the other thread starts to run, The UI thread seems to stuck in it, and won't update even the first UI update (complete white).
codes for the autoUpdate() method: (which is called on the last line of the UI onCreate method):
public void startAutoUpdateLogData(final int milliseconds){
continueAutoUpdate = true;
new Thread(){
#Override
public void run() {
while(continueAutoUpdate){
try{
Log.v("updating..", "");
updateLogFromDatabase();
Thread.sleep(milliseconds);
}catch(Exception e){
e.printStackTrace();
}
}
}
}.start();
}
OR:
public void startAutoUpdateLogData2(final int milliseconds){
continueAutoUpdate = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
while(continueAutoUpdate){
try{
Log.e("updating...", "");
updateLogFromDatabase();
Thread.sleep(milliseconds);
}catch(Exception e){
e.printStackTrace();
}
}
}
});
}
OR
public void startAutoUpdateLogData3(final int milliseconds){
continueAutoUpdate = true;
final Handler handler = new Handler();
runOnUiThread(new Runnable() {
#Override
public void run() {
while(continueAutoUpdate){
try{
handler.postDelayed(new Runnable(){
public void run(){
Log.e("updating...", "");
updateLogFromDatabase();
}
}, milliseconds);
}catch(Exception e){
e.printStackTrace();
}
}
}
});
}
Neither of these work.
You can do many ways. But this one will be more closer solution to what you have done.
private void runThread() {
new Thread() {
public void run() {
while (continueAutoUpdate) {
try {
handler.postDelayed(new Runnable(){
public void run(){
Log.e("updating...", "");
updateLogFromDatabase();
}
}, milliseconds);
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
After trying various stuff, I finally found the solution: Anytime you have some long-run tasks to perform, you can assign a new Java thread to execute it, but when there's a need to update the UI from that thread, which can't be directly accessing any components of the UI, So in that case you only need to wrap the code with runOnUiThread() inside the other thread. ex/
private void startAutoUpdateLogData(final int milliseconds) {
final Handler handler = new Handler();
continueAutoUpdate = true;
new Thread() {
public void run() {
while (continueAutoUpdate) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("updating...", "");
updateLogFromDatabase();
}
});
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

New activity after 100% in ProgressDialog

I've got this code:
#Override
public void onClick(View v) {
progressDoalog = new ProgressDialog(Hack.this);
progressDoalog.setMax(100);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("ProgressDialog bar example");
progressDoalog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDoalog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (progressDoalog.getProgress() <= progressDoalog
.getMax()) {
Thread.sleep(200);
handle.sendMessage(handle.obtainMessage());
if (progressDoalog.getProgress() == progressDoalog
.getMax()) {
progressDoalog.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Handler handle = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDoalog.incrementProgressBy(1);
}
};
});
}
}
Where can I add a code to open new activity when the ProgressDialog will be at 100%? Which and where exactly? Thanks for your help!
You can't start an Activity from a Dialog, but what you can do is start the Activity from the old one using a OnDismissListener.
Take a look at the documemtation :
https://developer.android.com/reference/android/content/DialogInterface.OnDismissListener.html
I haven't noticed but you can check the progress in your Handler, check if it's 100%, dismiss the dialog and start the new Activity, remember that you gotta do this on the UI thread

Starting a thread with a button

I'm programming a small android app in Java/eclipse.
In one part of my app i need a thread, as i build in the following way:
protected void onResume() {
super.onResume();
// we're going to simulate real time with thread that append data to the graph
new Thread(new Runnable() {
#Override
public void run() {
// we add 100 new entries
for (int i = 0; i < 100; i++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
addEntry();
}
});
// sleep to slow down the add of entries
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// manage error ...
}
}
}
}).start();
}
Evertything works fine so far. But now i want to start that thread not automatically. I want to handle ".start()" with a button.
How can i realize it?
I'm very new to Java and Android.
Thanks in Advance!
You can use Handler with Runnable instead of your Thread idea, Check out the following code, it server your purpose,
private Handler broadcastHandler;
private Runnable broadcastRunnable;
protected void onResume() {
super.onResume();
broadcastRunnable = new Runnable() {
#Override
public void run() {
// Your UI related operations
runOnUiThread(new Runnable() {
#Override
public void run() {
addEntry();
}
});
// Add some delay
broadcastHandler.postDelayed(broadcastRunnable, 1000);
}
}
public void onButtonClick(View view) {
broadcastHandler.postDelayed(broadcastRunnable, 1000);
}

How to 'flush' UI Thread actions before continue execution

I've got a problem in Android with runOnUiThread. I start an AsyncTask (inside an Activity) that waits for a while, and after calls the method showDialog(id). After this call, it sleeps for another while, and finishes calling the method dismissDialog(id).
This is the code:
public class MyActivity extends Activity {
...
protected class StartWaiting extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Show dialog
runOnUiThread(new Runnable() {
#Override
public void run() {
showDialog(PROGRESS_DIALOG_LOADING);
}
});
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Dismiss dialog
runOnUiThread(new Runnable() {
#Override
public void run() {
dismissDialog(PROGRESS_DIALOG_LOADING);
}
});
return null;
}
#Override
protected void onPostExecute(Void arg) {
new StartServices().execute();
}
}
}
Unfortunately, the behaviour is different from what I want to do: showDialog() and dismissDialog() are called one immediately after the other.
I think that the reason why this happens is that the UI Thread execute both actions "when it can", that is at the end of sleeping actions.
Well, does it exist some "flushUI()" method that force a thread (in this case, the UI Thread) to execute every action before continue?
You could just add a synchronization point in your thread, using a CountDownLatch for instance:
final CountDownLatch latch = new CountDownLatch(1);
view.post(new Runnable() {
public void run() {
try {
// Do stuff on the UI thread
} finally {
latch.countDown();
}
}
});
try {
if (!latch.await(CAPTURE_TIMEOUT, TimeUnit.MILLISECONDS)) {
return;
}
} catch (InterruptedException e) {
// Handle exception
}

Categories

Resources