เทียบเท่ากับ JavaScript setInterval / setTimeout ใน Android / Java คืออะไร?


129

ใครสามารถบอกฉันได้ว่ามีค่าเทียบเท่าสำหรับ setInterval / setTimeout สำหรับ Android หรือไม่ ใครมีตัวอย่างวิธีทำบ้างไหมคะ?

คำตอบ:


245

เช่นเคยกับ Android มีหลายวิธีในการทำเช่นนี้ แต่สมมติว่าคุณต้องการเรียกใช้โค้ดเล็กน้อยในภายหลังในเธรดเดียวกันฉันใช้สิ่งนี้:

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag", "This'll run 300 milliseconds later");
        }
    }, 
300);

.. นี่เทียบเท่ากับ

setTimeout( 
    function() {
        console.log("This will run 300 milliseconds later");
    },
300);

นี่เป็นทางออกที่ดีมากสำหรับการเลือกลิ้นชักและการแบ่งส่วน
ธุรกรรม

6
ฉันจะยกเลิกได้อย่างไรหากต้องการ?
Quentin Roy

คุณจะได้รับขอบเขตกิจกรรมภายในเมธอด run () ได้อย่างไร
Andy

@Andy like this:MyActivityName.this.myFunctionOnActivity()
Ben Clayton

1
@QuentinRoy: Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);และถ้าคุณต้องการยกเลิก:timeout.removeCallbacks(r);
Bastian Springer

101

setInterval ()

ฟังก์ชันที่ทำซ้ำตัวเองในทุกๆ n มิลลิวินาที

จาวาสคริ

 setInterval(function(){ Console.log("A Kiss every 5 seconds"); }, 5000);

เทียบเท่ากับJavaโดยประมาณ

new Timer().scheduleAtFixedRate(new TimerTask(){
    @Override
    public void run(){
       Log.i("tag", "A Kiss every 5 seconds");
    }
},0,5000);

setTimeout ()

ฟังก์ชันที่ใช้งานได้หลังจาก n มิลลิวินาทีเท่านั้น

จาวาสคริ

setTimeout(function(){ Console.log("A Kiss after 5 seconds"); },5000);

เทียบเท่ากับJavaโดยประมาณ

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag","A Kiss after 5 seconds");
        }
}, 5000);

5
สำหรับscheduleAtFixedRateวิธีนี้คุณจะยกเลิกตัวจับเวลาภายในกิจกรรมได้อย่างไรเมื่อกิจกรรมนั้นสิ้นสุดลง
auroranil

2
@ user824294 คุณสามารถบันทึกอินสแตนซ์ Timer ของคุณในตัวแปรและเรียก "ยกเลิก ()" เมื่อคุณต้องการหยุดงานที่กำหนดเวลาไว้ - Timer t = new Timer (); t.scheduleAtFixedRate ( ... ); - แล้วโทรหา t.cancel (); เมื่อใดก็ตามที่คุณต้องการ
Aebsubis

14

หากคุณไม่กังวลเกี่ยวกับการปลุกโทรศัพท์หรือนำแอปของคุณกลับมาจากความตายลอง:

// Param is optional, to run task on UI thread.     
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // Do the task...
        handler.postDelayed(this, milliseconds) // Optional, to repeat the task.
    }
};
handler.postDelayed(runnable, milliseconds);

// Stop a repeating task like this.
handler.removeCallbacks(runnable);

บนโทรศัพท์ของฉัน (Huawei P Smart) ตัวจัดการไม่ปลุกอุปกรณ์จากโหมดสลีป ( ตามที่ apanloco กล่าวไว้ในคำตอบอื่น )
Franco

13

ขึ้นอยู่กับสิ่งที่คุณต้องการบรรลุคุณควรดูที่ Android Handlers:

http://developer.android.com/reference/android/os/Handler.html

หากก่อนหน้านี้คุณเคยใช้ javascript setTimeout () etc เพื่อกำหนดเวลาให้งานรันในอนาคตนี่เป็นวิธีการดำเนินการของ Android (postDelayed / sendMessageDelayed)

โปรดทราบว่าเครื่องจัดการหรือตัวจับเวลาไม่ทำให้โทรศัพท์ Android ปลุกจากโหมดสลีป กล่าวอีกนัยหนึ่งคือหากคุณต้องการกำหนดเวลาบางสิ่งบางอย่างให้เกิดขึ้นจริงแม้ว่าหน้าจอจะปิดอยู่ / cpu อยู่ในโหมดสลีปคุณต้องตรวจสอบ AlarmManager ด้วย


5

ฉันไม่รู้เกี่ยวกับ JavaScript มากนัก แต่ฉันคิดว่าตัวจับเวลาอาจเป็นสิ่งที่คุณกำลังมองหา

http://developer.android.com/reference/java/util/Timer.html

จากลิงค์:

One-shot ถูกกำหนดให้ทำงานในเวลาที่แน่นอนหรือหลังจากการหน่วงเวลาสัมพัทธ์ งานที่เกิดขึ้นประจำจะถูกกำหนดโดยมีระยะเวลาคงที่หรืออัตราคงที่


หมายเหตุ: เรียกคุณบนเธรดพื้นหลังไม่ใช่เธรดหลัก / UI
ปาง

นี่ไม่ใช่คำตอบ แต่เป็นการอ้างอิงถึงข้อมูลภายนอกที่อาจมีหรือไม่มีโซลูชัน OPs กรุณาวางรหัสที่เกี่ยวข้อง OP สามารถใช้ได้!
เลฟ

5

คำตอบแรกคือคำตอบที่ถูกต้องและเป็นสิ่งที่ฉันใช้เวอร์ชันแลมด้านี้ซึ่งสั้นกว่ามากในไวยากรณ์ เนื่องจาก Runnable มีเมธอดการแทนที่ "run ()" เพียง 1 วิธีเราจึงสามารถใช้แลมด้า:

this.m_someBoolFlag = false;
new android.os.Handler().postDelayed(() -> this.m_someBoolFlag = true, 300);

5
import java.util.Timer;
import java.util.TimerTask;

class Clock {
    private Timer mTimer = new Timer();

    private int mSecondsPassed = 0;
    private TimerTask mTask = new TimerTask() {
        @Override
        public void run() {
            mSecondsPassed++;
            System.out.println("Seconds passed: " + mSecondsPassed);
        }
    };

    private void start() {
        mTimer.scheduleAtFixedRate(mTask, 1000, 1000);
    }

    public static void main(String[] args) {
        Clock c = new Clock();
        c.start();
    }
}

4

นี่คือคุณสมบัติที่เทียบเท่า setTimeout ซึ่งส่วนใหญ่มีประโยชน์เมื่อพยายามอัปเดตส่วนติดต่อผู้ใช้หลังจากเกิดความล่าช้า

ดังที่คุณทราบแล้วการอัปเดตส่วนต่อประสานผู้ใช้สามารถทำได้จากเธรด UI เท่านั้น AsyncTask ทำเพื่อคุณโดยเรียกใช้เมธอด onPostExecute จากเธรดนั้น

new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // Update the User Interface
        }

    }.execute();

3
1.ในทำนองเดียวกันยังสามารถนำมาใช้ในการจำลองonProgressUpdate() 2.วิ่งบนสระว่ายน้ำด้าย (หรือเพียงแค่หัวข้อเดียว) ดังนั้น อาจต้องรอจนกว่าอีกครั้งจะเสร็จสิ้น . มันจะขึ้นหนึ่งเธรดจากพูล setInterval() AsyncTaskAsyncTask
ปาง

มีปัญหามากมายในการใช้งาน async ในบริบทนี้ (มีเพียงเธรดเดียวและการล็อกเธรดโดยไม่มีเหตุผล) - วิธีแก้ปัญหาอื่น ๆ นั้นดีกว่ามาก
Elemental

4

ฉันกำลังสร้างเครื่องเล่น mp3 สำหรับ Android ฉันต้องการอัปเดตเวลาปัจจุบันทุกๆ500 มิลลิวินาทีดังนั้นฉันจึงทำเช่นนี้

setInterval

private void update() {
    new android.os.Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            long cur = player.getCurrentPosition();
            long dur = player.getDuration();
            currentTime = millisecondsToTime(cur);
            currentTimeView.setText(currentTime);
            if (cur < dur) {
                updatePlayer();
            }

            // update seekbar
            seekBar.setProgress( (int) Math.round((float)cur / (float)dur * 100f));
        }
    }, 500);
}

ซึ่งเรียกวิธีการเดียวกันแบบวนซ้ำ


0

Kotlin:

คุณยังสามารถใช้ CountDownTimer:

class Timer {
    companion object {
        @JvmStatic
        fun call(ms: Long, f: () -> Unit) {
            object : CountDownTimer(ms,ms){
                override fun onFinish() { f() }
                override fun onTick(millisUntilFinished: Long) {}
            }.start()
        }
    }
}

และในรหัสของคุณ:

Timer.call(5000) { /*Whatever you want to execute after 5000 ms*/ }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.