2017-10-14 4 views
0

私は更新時間のアルゴリズムを簡単にすることにしました。どこでもアルゴリズムタイマーを通して書きなさい。しかし、Runnableをメインアクティビティのインターフェイスに実装すると、追加のオブジェクトの作成を避けることができます。実装による時間の更新Runnable

アクティブ化を開くと、1秒ごとに更新されます。しかし、これは起こりません。 私が作成したタグ(ITTERATION)によって、繰り返しが1つしかありません。 HERE

Screenshot of phone preview and logs

から例を使用して、私はすでに私の脳を破りました。 あなたが使用している場合を除いて...そのままrun()が処理している...私は

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

関連する? https://stackoverflow.com/questions/9884246/ tv.setTextを呼び出す前にロギングを試してください。私はそこに例外がスローされたと思う。 – WorldSEnder

+0

私は例外がない。または、ログが表示されないか、時刻が再度表示されます。 – magistr4815

+0

'ScheduledExecutorService'は例外を抑制します。さらに、1つの例外を除いて、実行可能ファイルはデフォルトではスケジュールされていません。あなたのrunメソッド本体をtry-catchで囲み、あなた自身でログを取って、それがどうなるか確認してください。 – WorldSEnder

答えて

0

アプリケーションのメインスレッド(GUIスレッド)からのみViewを変更することができます。ScheduledExecutorServicerunを呼び出すと、別のスレッドで実行されます。結果はtv.setText(time);がスローされますCalledFromWrongThreadException。今度のスケジューラは、Runnableが例外をスローしたことを見て、将来exectionsを抑制します:

Documentation for ScheduledExecutorService

タスクのいずれかの実行が例外に遭遇した場合、後続の実行があり

を抑制しています一見、矛盾していること、説明することが残っていることです:それは一度動作します。これは、最初の遅延が0であるためです。これは、ScheduledExecutorService#scheduleAtFixedRateを呼び出すと、最初の実行が同期して実行される可能性があることを意味します。


この問題を解決するために、あなたはあなたのメインスレッドからtv.setText(time)を呼び出す必要があります。その方法はthis questionにあります。

-1

私はアンドロイドに適用さではなく、午前:(してください一度だけ
ヘルプ:

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

この回答は間違っています。 'ScheduledExecutorService#scheduleAtFixedRate'は繰り返し実行されることになっています – WorldSEnder

+0

私はRunメソッドを毎秒行う関数(scheduleAtFixedRate)を持っています。私にはそれを絶えず行うサイクルがあります。 – magistr4815

0

@WorldSEnder!ありがとうございました! 例外がありました"android.view.ViewRootImpl $ CalledFromWrongThreadException:ビュー階層を作成した元のスレッドのみがそのビュー"に触れることができます。 scheduleAtFixedRateによって呼び出された新しいスレッドは、テキストフィールドのテキストを更新できませんでした。 ハンドラーによって問題を解決しました。

Timerを使用する方が簡単で、最適化されました。 それを最適化する方法はありますか?

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"); 
    } 
} 
関連する問題