I want to set some code on a timer, but when I use a Timer I get an android.view.ViewRootImpl$CalledFromWrongThreadException. So I was wondering if there's any other way to code this so I don't get an error? I've looked into using some other timers that repeat code, but they all seem to use a public void in them and would assumedly do the same thing.
TimerTask task = new TimerTask() {
@Override
public void run() {
rvMessagesSubjectGroupPage.setLayoutManager(new LinearLayoutManager(SubjectGroupPage.this, RecyclerView.VERTICAL, true));
final ArrayList<MessageObj> messages = new ArrayList<>();
ArrayList<MessageObj> messagesAdap = readMessages(rvMessagesSubjectGroupPage, messages);
mMessageAdapter = new MessageListAdapter(SubjectGroupPage.this, messagesAdap);
rvMessagesSubjectGroupPage.setAdapter(mMessageAdapter);
rvMessagesSubjectGroupPage.scrollToPosition(5);
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1000;
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
public ArrayList<MessageObj> readMessages(final RecyclerView rv, final ArrayList<MessageObj> messages) {
db.collection("messagesIT")
.orderBy("Timesent", Query.Direction.DESCENDING)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task){
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
String message = document.getString("Message");
String senderName = document.getString("SenderName");
String sender = document.getString("Sender");
Timestamp ts = document.getTimestamp("Timesent");
Date timesent = ts.toDate();
MessageObj mess;
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
if (currentUser.getUid().equals(sender)) {
mess = new MessageObj(message, sender, senderName, timesent, true);
editor.putBoolean("isCurrentUser", true);
editor.commit();
} else {
mess = new MessageObj(message, sender, senderName, timesent, false);
editor.putBoolean("isCurrentUser", false);
editor.commit();
}
messages.add(mess);
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
showToast("There has been an error, please try again later.");
Log.d(TAG, "Error: " + e);
}
});
return messages;
}
Error:
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: oxley.it.collectivelearning, PID: 9784
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8161)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1391)
at android.view.View.requestLayout(View.java:22384)
at android.view.View.requestLayout(View.java:22384)
at android.view.View.requestLayout(View.java:22384)
at android.view.View.requestLayout(View.java:22384)
at android.view.View.requestLayout(View.java:22384)
at android.view.View.requestLayout(View.java:22384)
at androidx.constraintlayout.widget.ConstraintLayout.requestLayout(ConstraintLayout.java:3172)
at android.view.View.requestLayout(View.java:22384)
at androidx.recyclerview.widget.RecyclerView.requestLayout(RecyclerView.java:4202)
at android.view.ViewGroup.removeAllViews(ViewGroup.java:5577)
at androidx.recyclerview.widget.RecyclerView$5.removeAllViews(RecyclerView.java:900)
at androidx.recyclerview.widget.ChildHelper.removeAllViewsUnfiltered(ChildHelper.java:193)
at androidx.recyclerview.widget.RecyclerView.setLayoutManager(RecyclerView.java:1334)
at oxley.it.collectivelearning.SubjectGroupPage$6.run(SubjectGroupPage.java:138)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)