I can't solve this error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
TextView score;
private SharedPreferences speicher;
private SharedPreferences.Editor editor;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    score = (TextView) findViewById(R.id.score);
    speicher = getApplicationContext().getSharedPreferences("Daten", 0);
    editor = speicher.edit();
    loadfile("score" , score);
    new Timer().scheduleAtFixedRate(new TimerTask() {
        public void run() {
            Integer scorealt = Integer.parseInt(speicher.getString("score", null));
            Integer scorenewe = scorealt + Integer.parseInt(speicher.getString("anz", null));
            score.setText(scorenewe.toString());
            savefile("score", scorenewe.toString());
        }
    }, 0, 2000);
}
And I can't change score. score.setText(scorenewe.toString()); in line 45
android.view.ViewRootImpl$CalledFromWrongThreadException: 
    Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7769)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1332)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5446)
at android.view.View.invalidateInternal(View.java:14750)
at android.view.View.invalidate(View.java:14714)
at android.view.View.invalidate(View.java:14698)
at android.widget.TextView.checkForRelayout(TextView.java:8535)
at android.widget.TextView.setText(TextView.java:5076)
at android.widget.TextView.setText(TextView.java:4901)
at android.widget.TextView.setText(TextView.java:4876)
at de.yt.tutorial.Home$1.run(Home.java:45)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
To fix this error, wrap the code that has to be executed on UI thread in a Runnable instance passed to runOnUiThread() method.
Basically what runOnUiThread() will do is - Runs the specified action on the UI thread. It will check the current thread and if it finds its the MainThread it will execute that task immediately , otherwise first it will switch you to app MainThread and then it will execute the given task.
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue . Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler it is bound to a Looper .
It is because you're trying to touch the view while not in the UI thread.
Quick fix looks like this:
code before
score.setText(scorenewe.toString());
code after:
new Handler(Looper.getMainLooper()).post(new Runnable(){
    @Override
    public void run() {
        score.setText(scorenewe.toString());
    }
});
This way you will tell Android framework to run this line of code in the main UI thread, where you can touch any view you want P.S. read this
Solution:
new Timer().scheduleAtFixedRate(new TimerTask() {
        public void run() {
                RunOnUiThread(new Runnable() {
      @Override
      public void run() {
        Integer scorealt = Integer.parseInt(speicher.getString("score", null));
            Integer scorenewe = scorealt + Integer.parseInt(speicher.getString("anz", null));
            score.setText(scorenewe.toString());
            savefile("score", scorenewe.toString());
        }
    }
    }, 0, 2000);
function RunOnUIThread is an Activity function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With