2017-10-14 2 views
0

Ich entschloss mich, den Aktualisierungszeitalgorithmus zu vereinfachen. Überall schreiben Sie einen Algorithmus über den Timer. Aber wenn Sie Runnable die Schnittstelle in der Hauptaktivität implementieren, können Sie vermeiden, ein zusätzliches Objekt zu erstellen.Aktualisierungszeit durch Implementierung Runable

Ich möchte es, wenn ich die Aktivierung öffne, wurde die Zeit jede Sekunde aktualisiert. Aber das passiert nicht. Durch das von mir erstellte Tag (ITTERATION) gibt es nur eine Iteration. Anhand eines Beispiels aus HERE

Screenshot of phone preview and logs

Ich brach bereits mein Gehirn. Helfen Sie mir bitte :(

package pac.twoproject; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 

import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.TimeUnit; 

public class Main2Activity extends AppCompatActivity implements Runnable { 

    private static final String TAG = "ITTERATION"; 
    TextView tv; 
    String time; 

    final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main2); 

     tv = (TextView) findViewById(R.id.textView); 
     //scheduler.scheduleAtFixedRate(this, 0, 10, TimeUnit.MILLISECONDS); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     scheduler.scheduleAtFixedRate(this, 0, 1000, TimeUnit.MILLISECONDS); 
    } 

    @Override 
    public void run() { 
     time = sdf.format(new Date(System.currentTimeMillis())); 
     tv.setText(time); 
     Log.d(TAG, time); 
    } 
} 
+0

In Verbindung stehend? https://StackOverflow.com/questions/9884246/ Versuchen Sie sich zu protokollieren, bevor Sie den Anruf an tv.setText tätigen. Ich vermute, dass dort eine Ausnahme geworfen wird – WorldSEnder

+0

Ich bekomme keine Ausnahme.Oder das Protokoll wird nicht angezeigt oder die Uhrzeit wird erneut angezeigt. – magistr4815

+0

'ScheduledExecutorService' unterdrückt Ausnahmen. Nach einer Ausnahme ist das Runnable standardmäßig nicht geplant. Wickeln Sie Ihren run-Methodenkörper in einen try-catch und loggen Sie sich selbst ein, um zu sehen, ob das passiert. – WorldSEnder

Antwort

0

Sie können nur View s aus dem Hauptthread (GUI-Thread) der Anwendung ändern.In Ihrem Fall, wenn die ScheduledExecutorService ruft run, wird es in einem anderen Thread tun. Das Ergebnis ist, dass tv.setText(time); wirft eine CalledFromWrongThreadException. Der Scheduler wiederum zu sehen, dass die Runnable eine Ausnahme ausgelöst hat, künftig exections unterdrücken:

Documentation for ScheduledExecutorService

Wenn eine Ausführung der Aufgabe, eine Ausnahme trifft, werden nachfolgende Ausführungen

unterdrückt

Es ist ein scheinbar widersprüchliches Ding, das noch erklärt werden muss: Es funktioniert einmal. Dies liegt daran, dass Ihre anfängliche Verzögerung 0 ist. Dies bedeutet wiederum, dass die erste Ausführung möglicherweise synchron ausgeführt wird, wenn ScheduledExecutorService#scheduleAtFixedRate aufgerufen wird.


um dieses Problem zu beheben, müssen Sie tv.setText(time) von Ihrem Haupt-Thread nennen. Wie man das macht, finden Sie in this question.

-1

ich nicht auf Android angewendet bin, aber ... run() Verarbeitung ist, wie es ist ...
nur einmal außer wenn Sie verwenden:

while (true) { 
    time = sdf.format(new Date(System.currentTimeMillis())); 
    tv.setText(time); 
    Log.d(TAG, time); 
} 
+0

Diese Antwort ist falsch. 'ScheduledExecutorService # scheduleAtFixedRate' soll sich um wiederholte Ausführung kümmern – WorldSEnder

+0

Ich habe eine Funktion (scheduleAtFixedRate), die die Run-Methode jede Sekunde ausführt. Was für mich ein Zyklus, der es ständig tun wird. – magistr4815

0

Der Administrator half @WorldSEnder! Vielen Dank! Es gab eine Ausnahme "android.view.ViewRootImpl $ CalledFromWrongThreadException: Nur der ursprüngliche Thread, der eine Ansichtshierarchie erstellt hat, kann seine Ansichten berühren". Ein neuer Thread, der von der Funktion scheduleAtFixedRate aufgerufen wird, konnte den Text in dem Textfeld nicht aktualisieren. Das Problem wurde durch Handler gelöst.

Es war einfacher und optimierter, es über Timer zu tun. Oder haben Sie eine Idee, wie Sie es optimieren können?

package pac.twoproject; 

import android.os.Handler; 
import android.os.Message; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 

import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 


public class Main2Activity extends AppCompatActivity implements Runnable { 

    private static final String TAG = "ITTERATION"; 
    TextView tv; 
    String time; 
    Handler h; 

    final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main2); 

     tv = (TextView) findViewById(R.id.textView); 

     h = new Handler() { //создаем наш хендл, в котором пропишем получение из очереди сообщения и обновление нашей переменной 
      public void handleMessage(Message msg) { 
       Bundle bundle = msg.getData(); // достаем их сообщение наш бондаж 
       String text = bundle.getString("key"); // из бондажа уже наше сообщение 
       tv.setText(text); 
      } 
     }; 

     scheduler.scheduleAtFixedRate(this, 0, 1000, TimeUnit.MILLISECONDS); // функция которая запускает метод ран в новом потоке и повторяем его запуск каждую секунду 
    } 


    @Override 
    public void run() { 

     try { // мониторим код 
      time = sdf.format(new Date(System.currentTimeMillis())); // считываем время 
      Log.d(TAG, time); // пишем его лог 

      Message msg = Message.obtain(); // создаем новое сообщение 
      Bundle bundle = new Bundle(); // создаем новый сверток (бандаж) 
      bundle.putString("key", time); // в него пихаем по ключу наше время (текст) 
      msg.setData(bundle); // и уже бондаж запихиваем в сообщение 
      h.sendMessage(msg); //отправляем сообщение 
     } catch (RuntimeException e) { 
      Log.d(TAG, ""+ e); 
     } 
     Log.d(TAG, "1"); 
    } 
} 
Verwandte Themen