Android - периодически запускает метод, используя вызов postDelayed()
У меня есть ситуация в приложении для Android, где я хочу начать сетевую активность (отправка некоторых данных), которая должна запускаться каждую секунду. Я достигаю этого следующим образом:
В onCreate()
у меня есть код:
tv = new TextView(this);
tv.postDelayed(sendData, 1000);
Функция sendData()
:
Handler handler = new Handler();
private Runnable sendData=new Runnable(){
public void run(){
try {
//prepare and send the data here..
handler.removeCallbacks(sendData);
handler.postDelayed(sendData, 1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
Проблема возникает следующим образом: Когда пользователь нажимает кнопки назад и приложение выходит (пользовательский интерфейс исчезает), функция sendData()
все еще выполняется, и это то, что я хочу. Теперь, когда пользователь перезапускает приложение, мой onCreate()
снова вызывается, и я получаю sendData()
, вызывается два раза в секунду. Так и происходит. Каждый раз, когда пользователь выходит и запускается снова, происходит еще одна sendData()
в секунду.
Что я делаю неправильно? Это моя проблема с new Handler()
? Каков наилучший способ справиться с этим? Я хочу один вызов sendData()
в секунду, пока пользователь не покинет приложение (менеджер приложений формы).
Ответы
Ответ 1
Почему вы не создаете сервис и не ставите логику в onCreate()
. В этом случае, даже если вы нажмете кнопку "Назад", служба продолжит выполнение. и как только вы входите в приложение, он не будет звонить
onCreate()
снова. Скорее он назовет onStart()
Ответ 2
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
Toast.makeText(c, "check", Toast.LENGTH_SHORT).show();
handler.postDelayed(this, 2000);
}
}, 1500);
Ответ 3
Возможно, для достижения этого требуются методы жизненного цикла активности:
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler.post(sendData);
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendData);
}
private final Runnable sendData = new Runnable(){
public void run(){
try {
//prepare and send the data here..
handler.postDelayed(this, 1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
В этом подходе, если вы нажмете клавишу "назад" в своей деятельности или вызовите finish();
, она также остановит вызовы postDelayed.
Ответ 4
Вы можете упростить код следующим образом.
В Java:
new Handler().postDelayed (() -> {
//your code here
}, 1000);
В Котлине:
Handler().postDelayed({
//your code here
}, 1000)
Ответ 5
Пожалуйста, проверьте ниже, что он работает на моей стороне в нижнем коде, ваш обработчик будет запускаться через каждые 1 секунду, когда вы находитесь на той же самой активности.
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
runnable = new Runnable()
{
@Override
public void run()
{
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
Ответ 6
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==0){
// do stuff
h.removeMessages(0); // clear the handler for those messages with what = 0
h.sendEmptyMessageDelayed(0, 2000);
}
}
};
h.sendEmptyMessage(0);
Ответ 7
Я думаю, вы могли бы экспериментировать с разными флагами активности, поскольку это звучит как несколько экземпляров.
"SingleTop"
"SingleTask"
"SingleInstance"
Я бы попробовал те, которые могут быть определены внутри манифеста.
http://developer.android.com/guide/topics/manifest/activity-element.html
Ответ 8
Вы должны установить andrid: allowRetainTaskState = "true" для запуска Activity в Manifest.xml. Если эта активация не запускает активность. вы должны установить андроид: launchMode = "singleTask" в этом действии