X 초마다 메서드를 실행하는 방법


114

Android 2.3.3 애플리케이션을 개발 중이며 X 초 마다 메서드를 실행해야합니다 .

iOS에서는 NSTimer 가 있지만 Android에서는 무엇을 사용해야할지 모르겠습니다.

누군가 나에게 Handler를 추천했습니다 . 다른 사람은 나를 AlarmManager 권장 하지만 어떤 방법이 NSTimer 에 더 잘 맞는지 모르겠습니다 .

이것은 Android에서 구현하려는 코드입니다.

timer2 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f)
    target:self
    selector:@selector(loopTask)
    userInfo:nil
    repeats:YES
];

timer1 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f)
    target:self
    selector:@selector(isFree)
    userInfo:nil
    repeats:YES
];

NSTimer 처럼 작동하는 것이 필요합니다 .

나에게 무엇을 추천합니까?


1
"최고의 것"을 정의하십시오. 어떤면에서 최고가되기를 원하십니까?
Simon Forsberg 2012

NSTimer에 어떤 방법이 더 적합한 지 모르겠습니다.
VansFannel 2012

@VansFannel 얼마나 긴 간격을 원하십니까?
FoamyGuy 2012

내가하려는 작업에 대한 세부 정보로 질문을 업데이트했습니다.
VansFannel

이 질문 : stackoverflow.com/questions/6242268/… , 이 질문 과 유사하며 훌륭한 답변이 있습니다.
VansFannel

답변:


168

이것은 함수를 실행하는 데 필요한 간격에 따라 다릅니다.

=> 10 분이면 → 알람 매니저로 갈 것입니다.

// Some time when you want to run
Date when = new Date(System.currentTimeMillis());    

try{
   Intent someIntent = new Intent(someContext,MyReceiver.class); // intent to be launched

   // note this could be getActivity if you want to launch an activity
   PendingIntent pendingIntent = PendingIntent.getBroadcast(
        context, 
        0, // id, optional
        someIntent, // intent to launch
        PendingIntent.FLAG_CANCEL_CURRENT); // PendintIntent flag

   AlarmManager alarms = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE);

   alarms.setRepeating(AlarmManager.RTC_WAKEUP,
        when.getTime(),
        AlarmManager.INTERVAL_FIFTEEN_MINUTES,
        pendingIntent); 

}catch(Exception e){
   e.printStackTrace();
}

그런 다음 방송 수신기를 통해 이러한 방송을 수신합니다. 이것은 응용 프로그램 매니페스트 또는 context.registerReceiver(receiver,filter);방법을 통해 등록되어야 합니다. Broadcast Receiver에 대한 자세한 내용은 공식 문서를 참조하십시오. 방송 수신기 .

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
         //do stuffs
    }
}

= <10 분이면 → 핸들러와 함께 가겠습니다.

Handler handler = new Handler();
int delay = 1000; //milliseconds

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);

3
시간 지연에 따라 제안이 다른 이유는 무엇입니까?
Simon Forsberg

7
효율성, AlarmManager 문서에는 작은 간격의 반복 작업에 사용해서는 안된다고 명시되어 있습니다.
Jug6ernaut

9
AlarmManager 문서 에서 @ SimonAndréForsberg는 Handler가 짧은 틱에 사용하기에 선호되고 더 효율적인 방법 이라고 말합니다. "참고 : Alarm Manager는 특정 시간에 애플리케이션 코드를 실행하려는 경우를위한 것입니다. 응용 프로그램이 현재 실행되고 있지 않습니다. 정상적인 타이밍 작업 (틱, 타임 아웃 등)의 경우 Handler를 사용하는 것이 더 쉽고 훨씬 효율적입니다. "
FoamyGuy 2012-07-11

그러나 AlarmManager를 시작한 동일한 활동에서 메서드를 실행해야합니다. 어떻게 할 수 있습니까?
VansFannel 2012

2
실행 파일 내에서 @ahmadalibaloch 할 수 있습니다 h.removeCallbacks(this);. 그렇지 않으면 제거 할 수 있도록 실행 파일에 대한 참조를 유지해야합니다. 두 번째 방법이 필요한 경우 여기에 게시 된 방법이 최선의 방법이 아닐 수 있습니다.
Jug6ernaut

101

1 초마다 타이머 사용 ...

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //your method
    }
}, 0, 1000);//put here time 1000 milliseconds=1 second

내가하려는 작업에 대한 세부 정보로 질문을 업데이트했습니다.
VansFannel

4
타이머 ( mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler )를 사용 하지 말고 Handler 또는 ScheduledThreadPoolExecutor를 사용하십시오.
AppiDevo

69

이 코드를 사용하여 onResume ()을 통해 15 초마다 핸들러를 호출하고 onPause ()를 통해 활동이 표시되지 않을 때 중지 할 수 있습니다.

Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000; //Delay for 15 seconds.  One second = 1000 milliseconds.


@Override
protected void onResume() {
   //start handler as activity become visible

    handler.postDelayed( runnable = new Runnable() {
        public void run() {
            //do something

            handler.postDelayed(runnable, delay);
        }
    }, delay);

    super.onResume();
}

// If onPause() is not included the threads will double up when you 
// reload the activity 

@Override
protected void onPause() {
    handler.removeCallbacks(runnable); //stop handler when activity not visible
    super.onPause();
}

5
이것이 제가 찾던 것입니다. 완전한.
viper

3
그것은 완벽한 대답입니다!
Riddhi

에 딱 맞다! TabLayout에서 MainActivitys 현재 선택된 탭을 확인하는 데 사용하고 작업을 중지하지 않으면-TabLayout이 선택한 탭의 양쪽 탭을 선택하면 onPause ()가 실패하므로
BENN1TH

완전한. 이것은 내가 찾던 것입니다 :) 1 질문, 다른 활동 에서이 메서드를 호출 할 수 있습니까? 아니면이 활동을 막 으면이 개체가 파괴됩니까? 정적 핸들러 및 실행 가능을 생성하면 어떻게됩니까? 가능합니까?
hyperCoder

17

RxJava에 익숙하다면 꽤 깔끔한 Observable.interval ()을 사용할 수 있습니다.

Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(new Function<Long, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(@NonNull Long aLong) throws Exception {
                    return getDataObservable(); //Where you pull your data
                }
            });

이것의 단점은 다른 방식으로 데이터 폴링을 설계해야한다는 것입니다. 그러나 리 액티브 프로그래밍 방식에는 많은 이점이 있습니다.

  1. 콜백을 통해 데이터를 제어하는 ​​대신 구독하는 데이터 스트림을 만듭니다. 이렇게하면 "데이터 폴링"논리와 "데이터로 UI 채우기"논리가 분리되므로 "데이터 소스"코드와 UI 코드를 혼합하지 않습니다.
  2. RxAndroid를 사용하면 단 2 줄의 코드로 스레드를 처리 할 수 ​​있습니다.

    Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(...) // polling data code
          .subscribeOn(Schedulers.newThread()) // poll data on a background thread
          .observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread
          .subscribe(...); // your UI code

RxJava를 확인하십시오. 학습 곡선이 높지만 Android에서 비동기 호출을 훨씬 쉽고 깔끔하게 처리 할 수 ​​있습니다.


4

Kotlin을 사용하여 이제이를위한 일반 함수를 만들 수 있습니다!

object RepeatHelper {
    fun repeatDelayed(delay: Long, todo: () -> Unit) {
        val handler = Handler()
        handler.postDelayed(object : Runnable {
            override fun run() {
                todo()
                handler.postDelayed(this, delay)
            }
        }, delay)
    }
}

그리고 사용하려면 다음을 수행하십시오.

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
    myRepeatedFunction()
}

3
    new CountDownTimer(120000, 1000) {

        public void onTick(long millisUntilFinished) {
            txtcounter.setText(" " + millisUntilFinished / 1000);

        }

        public void onFinish() {

            txtcounter.setText(" TimeOut  ");
            Main2Activity.ShowPayment = false;
            EventBus.getDefault().post("go-main");

        }

    }.start();

4
코드 만 게시하지 마십시오. 제발 편집 답변을 몇 가지 설명을 추가 할 수 있습니다.
Shashanth

2

여기에서는 onCreate () 활동에서 스레드를 반복적으로 사용했으며 타이머는 경우에 따라 모든 것을 허용하지 않습니다 스레드가 해결책입니다

     Thread t = new Thread() {
        @Override
        public void run() {
            while (!isInterrupted()) {
                try {
                    Thread.sleep(10000);  //1000ms = 1 sec
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE);
                            Gson gson = new Gson();
                            String json = mPrefs.getString("chat_list", "");
                            GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class);
                            String sam = "";

                            ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData());
                            listview.setAdapter(adapter);
                           // listview.setStackFromBottom(true);
                          //  Util.showMessage(Chat.this,"Merhabalar");
                        }
                    });

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    t.start();

필요한 경우 멈출 수 있습니다.

@Override
protected void onDestroy() {
    super.onDestroy();
    Thread.interrupted();
    //t.interrupted();
}

내 답변이 작동하지 않는 상황을 설명해주세요
Umar Ata

안녕하세요 Umar. 앱이 살아있는 내내 서클이 필요했고 Handler는 활동이 살아있는 동안 반복을 생겼지 만 다른 활동도 방문 할 수있는 동안 서클이 필요했습니다. 그래서 쓰레드는 이런 식으로 해결책이됩니다.
Sam

1

Rx JavaRx Android 사용 문제에 대한 유용한 답변이 여기 에 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.