it-swarm.com.de

Aktualisierung der Benutzeroberfläche mit Runnable & postDelayed funktioniert nicht mit der Timer-App

Ich habe mir jede Diskussion und jeden Thread angesehen, den ich finden kann, damit das funktioniert, aber es ist nicht so. Ich habe einen einfachen Timer, der eine Textansicht aktualisiert (mTimeTextField im Beispiel unten). Die Run-Methode mUpdateTimeTask wird korrekt (jede Sekunde) ausgeführt, das UI/Text-Feld wird jedoch nicht aktualisiert.

Ich habe Code basierend auf den hier gefundenen Informationen:

http://Android-developers.blogspot.com/2007/11/stitch-in-time.htmlhttp://developer.Android.com/resources/articles/timed-ui- updates.html

Hier ist der Code:

package com.something.handlertest;

import com.something.handlertest.R;

import Android.app.Activity;
import Android.content.Intent;
import Android.os.Bundle;
import Android.os.Handler;
import Android.os.SystemClock;
import Android.view.View;
import Android.widget.Button;
import Android.widget.TextView;

public class Test extends Activity {

    private Handler mHandler = new Handler(); 
    private int labelNo    = 0;
    private long currTime  = 0L;
    private long mStartTime = 0L;
    TextView mTimeTextField;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTimeTextField = (TextView)findViewById(R.id.timeTextFieldl);

        Button startButton = (Button)findViewById(R.id.start_button);
        startButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                   if (mStartTime == 0L) {
                        mStartTime = System.currentTimeMillis();
                        mHandler.removeCallbacks(mUpdateTimeTask);
                        mHandler.postDelayed(mUpdateTimeTask, 100);
                   }
            }
        });
    }

    private Runnable mUpdateTimeTask = new Runnable() {
           public void run() {
               final long start = mStartTime;
               //long millis = SystemClock.uptimeMillis() - start;
               long millis = SystemClock.uptimeMillis();
               int seconds = (int) (millis / 1000);
               int minutes = seconds / 60;
               seconds     = seconds % 60;

               //setContentView(mTimeTextField);  This will blow up if I use it

               if (seconds < 10) {
                   mTimeTextField.setText("" + minutes + ":0" + seconds);
               } else {
                   mTimeTextField.setText("" + minutes + ":" + seconds);            
               }

               //mHandler.postAtTime(this,
                   //    start + (((minutes * 60) + seconds + 1) * 1000));

               mHandler.postAtTime(this, 1000);
           }
        };

}

Ich habe versucht, einige Vorschläge hinzuzufügen: 

setContentView(mTimeLabel);

Dies wird jedoch zum Absturz bringen, dass die Ansicht keinen Elternteil hat. Zu Ihrer Information, ich habe eine:

setContentView(R.layout.main);

rufen Sie meine onCreate() an.

22
bdelliott

Ersetzen 

mHandler.postAtTime(this, 1000);

mit

mHandler.postDelayed(this, 1000);
19
Fedor
  1. Sie müssen UI-Aktualisierungen im UI-Thread durchführen.
  2. Sie müssen einen Handler im UI-Thread erstellen, um .__ auszuführen. Aufgaben im UI-Thread.

    public class MainActivity extends AppCompatActivity
        private Handler mHandler;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            mHandler = new Handler(); // This to create the Handler in the UI thread
            // ...
        }
    
5
david m lee

Möglicherweise entspricht dies mehr dem, wonach Sie suchen:

private Runnable mUpdateTimeTask = new Runnable() {
       public void run() {

           final long start = mStartTime;
           long elapseTime = System.currentTimeMillis() - start;
           int seconds = (int) (elapseTime / 1000);
           int minutes = seconds / 60;
           seconds     = seconds % 60;

           if (seconds < 10) {
               mTimeTextField.setText("" + minutes + ":0" + seconds);
           } else {
               mTimeTextField.setText("" + minutes + ":" + seconds);            
           }

           // add a delay to adjust for computation time
           long delay = (1000 - (elapseTime%1000));

           mHandler.postDelayed(this, delay);
       }
    };

Ich fand, dass dies eine gute Möglichkeit ist, den Videos eine Zeit hinzuzufügen

4
Laith Alnagem

ansicht kann nur im UI-Thread angezeigt werden. Sie müssen das Runnable mit ru starten

1

Bitte stellen Sie sicher, dass R.id.timeTextFieldl eine korrekte ID ist.

0
Fedor
if (seconds < 10) {
    mTimeTextField.setText("" + minutes + ":0" + seconds);
} else {
    mTimeTextField.setText("" + minutes + ":" + seconds);            
}

kürzer ist:

mTimeTextField.setText(minutes + ":" + (seconds < 10 ? "0" : "") + seconds);

besser ist jedoch die Verwendung von String.format ^

mTimeTextField.setText(String.format("%d:%s%d", minutes, (seconds < 10 ? "0" : ""), seconds);
0
Sergey