通过实现 Runnable 更新时间
Updating time through implementation Runnable
我决定简化更新时间算法。通过Timer到处写算法。但是如果你在主activity中实现Runnable接口,你可以避免创建一个额外的对象。
打开激活就想要,时间每秒更新一次。但这不会发生。
根据我创建的标签 (ITTERATION),只有一次迭代。
使用 HERE
中的示例
我已经脑残了。
请帮助我:(
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);
}
}
我没有申请 android 但是... run()
正在按原样处理...
仅一次 除非您使用:
while (true) {
time = sdf.format(new Date(System.currentTimeMillis()));
tv.setText(time);
Log.d(TAG, time);
}
您只能从应用程序的主线程(GUI 线程)修改 View
s。在您的例子中,当 ScheduledExecutorService
调用 run
时,它将在不同的线程中执行。结果是 tv.setText(time);
抛出 CalledFromWrongThreadException
。反过来,调度程序看到 Runnable
抛出异常,将抑制未来的执行:
Documentation for ScheduledExecutorService
If any execution of the task encounters an exception, subsequent executions are suppressed
有一个看似矛盾的东西需要解释:它只工作一次。这是因为您的初始延迟是 0
。反过来,这意味着在调用 ScheduledExecutorService#scheduleAtFixedRate
.
时,第一次执行可能是同步 运行
要解决此问题,您必须从主线程调用 tv.setText(time)
。如何操作,可在 this question.
中找到
管理员帮助@WorldSEnder!谢谢!
出现异常 "android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views"。函数 scheduleAtFixedRate 调用的新线程无法更新文本字段中的文本。
通过Handler.
解决了问题
通过 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");
}
}
我决定简化更新时间算法。通过Timer到处写算法。但是如果你在主activity中实现Runnable接口,你可以避免创建一个额外的对象。
打开激活就想要,时间每秒更新一次。但这不会发生。 根据我创建的标签 (ITTERATION),只有一次迭代。 使用 HERE
中的示例我已经脑残了。 请帮助我:(
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);
}
}
我没有申请 android 但是... run()
正在按原样处理...
仅一次 除非您使用:
while (true) {
time = sdf.format(new Date(System.currentTimeMillis()));
tv.setText(time);
Log.d(TAG, time);
}
您只能从应用程序的主线程(GUI 线程)修改 View
s。在您的例子中,当 ScheduledExecutorService
调用 run
时,它将在不同的线程中执行。结果是 tv.setText(time);
抛出 CalledFromWrongThreadException
。反过来,调度程序看到 Runnable
抛出异常,将抑制未来的执行:
Documentation for ScheduledExecutorService
If any execution of the task encounters an exception, subsequent executions are suppressed
有一个看似矛盾的东西需要解释:它只工作一次。这是因为您的初始延迟是 0
。反过来,这意味着在调用 ScheduledExecutorService#scheduleAtFixedRate
.
要解决此问题,您必须从主线程调用 tv.setText(time)
。如何操作,可在 this question.
管理员帮助@WorldSEnder!谢谢! 出现异常 "android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views"。函数 scheduleAtFixedRate 调用的新线程无法更新文本字段中的文本。 通过Handler.
解决了问题通过 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");
}
}