Cara menjalankan metode setiap X detik

114

Saya sedang mengembangkan aplikasi Android 2.3.3 dan saya perlu menjalankan metode setiap X detik .

Di iOS, saya memiliki NSTimer , tetapi di Android saya tidak tahu harus menggunakan apa.

Seseorang telah merekomendasikan saya Handler ; yang lain merekomendasikan saya AlarmManager tetapi saya tidak tahu metode mana yang lebih cocok dengan NSTimer .

Ini adalah kode yang ingin saya terapkan di 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
];

Saya butuh sesuatu yang berfungsi seperti NSTimer .

Apa yang Anda rekomendasikan untuk saya?

VansFannel
sumber
1
Tentukan "yang terbaik". Dalam hal apa Anda ingin menjadi yang terbaik?
Simon Forsberg
Saya tidak tahu metode mana yang lebih cocok dengan NSTimer.
VansFannel
@VansFannel Berapa lama interval yang Anda inginkan?
FoamyGuy
Saya telah memperbarui pertanyaan dengan detail tentang apa yang saya coba lakukan.
VansFannel
Pertanyaan ini: stackoverflow.com/questions/6242268/… , mirip dengan pertanyaan ini, dan memiliki jawaban yang bagus.
VansFannel

Jawaban:

168

Ini sangat tergantung pada berapa lama Anda perlu menjalankan fungsi.

Jika => 10 menit → Saya akan menggunakan Alarm Manager.

// 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();
}

Dan kemudian Anda menerima siaran ini melalui penerima siaran. Perhatikan bahwa eter ini perlu didaftarkan di manifes aplikasi Anda atau melalui context.registerReceiver(receiver,filter);metode. Untuk informasi lebih lanjut tentang Penerima Siaran, silakan merujuk ke Dokumen resmi. Penerima Siaran .

public class MyReceiver extends BroadcastReceiver{

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

Jika = <10minutes → Saya akan pergi dengan Handler.

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

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);
Jug6ernaut
sumber
3
Mengapa saran berbeda tergantung pada waktu tunda?
Simon Forsberg
7
Efisiensi, Dalam dokumen AlarmManager itu menyatakan bahwa itu tidak boleh digunakan untuk tugas berulang interval kecil.
Jug6ernaut
9
@ SimonAndréForsberg dalam dokumen AlarmManager menyatakan bahwa Handler adalah metode yang lebih disukai dan lebih efisien untuk digunakan untuk tanda centang pendek: "Catatan: Manajer Alarm ditujukan untuk kasus di mana Anda ingin kode aplikasi Anda dijalankan pada waktu tertentu, bahkan jika Anda aplikasi tidak sedang berjalan. Untuk operasi pengaturan waktu normal (ticks, timeout, dll) lebih mudah dan lebih efisien untuk menggunakan Handler. "
FoamyGuy
Tapi, saya perlu menjalankan metode dalam Aktivitas yang sama yang meluncurkan AlarmManager. Bagaimana saya bisa melakukan itu?
VansFannel
2
@ahmadalibaloch dari dalam runnable dapat Anda lakukan h.removeCallbacks(this);, jika tidak , Anda perlu mempertahankan referensi ke runnable agar dapat menghapusnya. Jika yang kedua diinginkan, metode yang diposting di sini mungkin bukan rute terbaik Anda.
Jug6ernaut
101

Gunakan Timer untuk setiap detik ...

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //your method
    }
}, 0, 1000);//put here time 1000 milliseconds=1 second
Samir Mangroliya
sumber
Saya telah memperbarui pertanyaan dengan detail tentang apa yang saya coba lakukan.
VansFannel
4
Jangan gunakan Timer ( mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler ), gunakan Handler atau ScheduledThreadPoolExecutor.
AppiDevo
69

Anda dapat mencoba kode ini untuk memanggil penangan setiap 15 detik melalui onResume () dan menghentikannya saat aktivitas tidak terlihat, melalui 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();
}
Umar Ata
sumber
5
Inilah yang saya cari. Sempurna.
viper
3
itulah Jawaban yang sempurna!
Riddhi
Tepat! Menggunakan untuk memeriksa tab MainActivitys saat ini dipilih di TabLayout cocok dengan fragmen ini dan jika tidak berhenti bekerja - karena onPause () gagal ketika tab mana pun yang dipilih TabLayout di kedua sisi tab yang dipilih ini
BENN1TH
sempurna. Ini yang saya cari :) 1 pertanyaan, dapatkah saya memanggil metode ini dari aktivitas lain. Atau jika saya melakukan aktivitas ini, objek ini akan dihancurkan? Bagaimana jika saya membuat handler statis dan dapat dijalankan. Apakah itu mungkin?
hyperCoder
17

Jika Anda sudah familiar dengan RxJava, Anda bisa menggunakan Observable.interval (), yang cukup rapi.

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
                }
            });

Sisi negatifnya adalah Anda harus merancang polling data Anda dengan cara yang berbeda. Namun, ada banyak manfaat dari cara Pemrograman Reaktif:

  1. Alih-alih mengontrol data Anda melalui panggilan balik, Anda membuat aliran data langganan Anda. Ini memisahkan perhatian logika "polling data" dan logika "mengisi UI dengan data Anda" sehingga Anda tidak mencampur kode "sumber data" dan kode UI Anda.
  2. Dengan RxAndroid, Anda dapat menangani utas hanya dalam 2 baris kode.

    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
    

Silakan periksa RxJava. Ini memiliki kurva belajar yang tinggi tetapi itu akan membuat penanganan panggilan asinkron di Android jadi lebih mudah dan lebih bersih.

wdina
sumber
4

Dengan Kotlin, sekarang kita dapat membuat fungsi umum untuk ini!

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

Dan untuk menggunakan, lakukan saja:

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
    myRepeatedFunction()
}
Luke
sumber
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();
Behzad F94
sumber
4
Jangan memposting kode hanya menjawab. Harap edit jawaban Anda dan tambahkan penjelasan.
Shashanth
2

Di sini saya menggunakan utas di onCreate () sebuah Aktivitas berulang kali, pengatur waktu tidak mengizinkan semuanya dalam beberapa kasus Thread adalah solusinya

     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();

Jika diperlukan, hal itu dapat dihentikan

@Override
protected void onDestroy() {
    super.onDestroy();
    Thread.interrupted();
    //t.interrupted();
}
Sam
sumber
tolong jelaskan situasi ketika jawaban saya tidak akan berhasil
Umar Ata
Halo Umar. Saya membutuhkan lingkaran sepanjang waktu aplikasi tersebut hidup, Handler membuat pengulangan hidup saat aktivitas masih hidup tetapi saya membutuhkan lingkaran saat saya dapat mengunjungi aktivitas lain juga. Jadi benang adalah solusi dengan cara ini pasti juga ada perjuangannya.
Sam
1

Di sini mungkin jawaban yang membantu untuk masalah Anda menggunakan Rx Java & Rx Android .

Sepehr
sumber