Android में टाइमर कैसे सेट करें?


325

क्या कोई व्यक्ति टेक्स्टफील्ड को हर सेकेंड अपडेट करने का एक सरल उदाहरण दे सकता है?

मैं एक उड़ने वाली गेंद बनाना चाहता हूं और गेंद को हर सेकंड में गणना / अद्यतन करने की आवश्यकता है, इसीलिए मुझे किसी प्रकार के टाइमर की आवश्यकता है।

मुझे यहां से कुछ नहीं मिला ।


14
यह वर्ग मदद कर सकता है: developer.android.com/reference/android/os/CountDownTimer.html
परमवीर सिंह

जवाबों:


463

ठीक है क्योंकि यह अभी तक साफ नहीं हुआ है, इसे संभालने के 3 सरल तरीके हैं। नीचे एक उदाहरण है जो सभी 3 दिखा रहा है और सबसे नीचे एक उदाहरण है जो मेरे द्वारा मानने के तरीके को दर्शाता है। यदि आवश्यक हो तो राज्य को बचाने के लिए ऑनपॉज में अपने कार्यों को साफ करने के लिए याद रखें।


import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class main extends Activity {
    TextView text, text2, text3;
    long starttime = 0;
    //this  posts a message to the main thread from our timertask
    //and updates the textfield
   final Handler h = new Handler(new Callback() {

        @Override
        public boolean handleMessage(Message msg) {
           long millis = System.currentTimeMillis() - starttime;
           int seconds = (int) (millis / 1000);
           int minutes = seconds / 60;
           seconds     = seconds % 60;

           text.setText(String.format("%d:%02d", minutes, seconds));
            return false;
        }
    });
   //runs without timer be reposting self
   Handler h2 = new Handler();
   Runnable run = new Runnable() {

        @Override
        public void run() {
           long millis = System.currentTimeMillis() - starttime;
           int seconds = (int) (millis / 1000);
           int minutes = seconds / 60;
           seconds     = seconds % 60;

           text3.setText(String.format("%d:%02d", minutes, seconds));

           h2.postDelayed(this, 500);
        }
    };

   //tells handler to send a message
   class firstTask extends TimerTask {

        @Override
        public void run() {
            h.sendEmptyMessage(0);
        }
   };

   //tells activity to run on ui thread
   class secondTask extends TimerTask {

        @Override
        public void run() {
            main.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                   long millis = System.currentTimeMillis() - starttime;
                   int seconds = (int) (millis / 1000);
                   int minutes = seconds / 60;
                   seconds     = seconds % 60;

                   text2.setText(String.format("%d:%02d", minutes, seconds));
                }
            });
        }
   };


   Timer timer = new Timer();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        text = (TextView)findViewById(R.id.text);
        text2 = (TextView)findViewById(R.id.text2);
        text3 = (TextView)findViewById(R.id.text3);

        Button b = (Button)findViewById(R.id.button);
        b.setText("start");
        b.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Button b = (Button)v;
                if(b.getText().equals("stop")){
                    timer.cancel();
                    timer.purge();
                    h2.removeCallbacks(run);
                    b.setText("start");
                }else{
                    starttime = System.currentTimeMillis();
                    timer = new Timer();
                    timer.schedule(new firstTask(), 0,500);
                    timer.schedule(new secondTask(),  0,500);
                    h2.postDelayed(run, 0);
                    b.setText("stop");
                }
            }
        });
    }

    @Override
    public void onPause() {
        super.onPause();
        timer.cancel();
        timer.purge();
        h2.removeCallbacks(run);
        Button b = (Button)findViewById(R.id.button);
        b.setText("start");
    }
}


याद रखने वाली मुख्य बात यह है कि यूआई को केवल मुख्य यूआई थ्रेड से संशोधित किया जा सकता है, इसलिए हैंडलर या एक्टिविटी का उपयोग करें। RunOnUIThread (Runnable r);

यहाँ मैं पसंदीदा तरीका मानता हूँ।


import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class TestActivity extends Activity {

    TextView timerTextView;
    long startTime = 0;

    //runs without a timer by reposting this handler at the end of the runnable
    Handler timerHandler = new Handler();
    Runnable timerRunnable = new Runnable() {

        @Override
        public void run() {
            long millis = System.currentTimeMillis() - startTime;
            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds = seconds % 60;

            timerTextView.setText(String.format("%d:%02d", minutes, seconds));

            timerHandler.postDelayed(this, 500);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_activity);

        timerTextView = (TextView) findViewById(R.id.timerTextView);

        Button b = (Button) findViewById(R.id.button);
        b.setText("start");
        b.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Button b = (Button) v;
                if (b.getText().equals("stop")) {
                    timerHandler.removeCallbacks(timerRunnable);
                    b.setText("start");
                } else {
                    startTime = System.currentTimeMillis();
                    timerHandler.postDelayed(timerRunnable, 0);
                    b.setText("stop");
                }
            }
        });
    }

  @Override
    public void onPause() {
        super.onPause();
        timerHandler.removeCallbacks(timerRunnable);
        Button b = (Button)findViewById(R.id.button);
        b.setText("start");
    }

}



1
@ डेव.बी, महान उदाहरण के लिए धन्यवाद। क्या आपके द्वारा उल्लिखित एक विधि बनाम एक विधि का उपयोग करने के कोई फायदे / नुकसान हैं?
गौतम

2
@ गौतम मेरा मानना ​​है कि ऊपर दिए गए सभी तरीके उसी के बारे में प्रदर्शन करते हैं। मैं व्यक्तिगत रूप से रन रनेबल और h2 हैंडलर के साथ ऊपर वर्णित विधि पसंद करता हूं क्योंकि यह एंड्रॉइड डेवलपर साइट द्वारा निर्धारित है और मेरी राय में सबसे सुरुचिपूर्ण भी है।
डेव.बी।

6
अच्छा होगा कि आपके पसंदीदा तरीके को बाकी कोड से अलग कर दिया जाए। जैसे आपके पास एक उदाहरण हो सकता है कि आप अपना पसंदीदा तरीका दिखा सकते हैं और दूसरा विकल्प दिखा सकता है। एक साथ सभी तीन तरीकों के होने से यह समझना मुश्किल हो जाता है कि क्या चल रहा है (मेरे जैसे एंड्रॉइड नौसिखिया के लिए विशिष्ट)। शायद बहुत ज्यादा पूछ रहा है :)
जेसी एल्ड्रिज

4
@ जेसे एल्ड्रिज अच्छा विचार है। मैं आगे बढ़ गया और केवल पसंदीदा विधि के साथ कोड जोड़ा।
डेव.बी।

1
@bluesm मैंने ईमानदारी से सिर्फ इसके बारे में नहीं सोचा था लेकिन हां यह ठीक काम करेगा।
डेव।

84

यह आसान है! आप नया टाइमर बनाएँ।

Timer timer = new Timer();

फिर आप टाइमर कार्य का विस्तार करते हैं

class UpdateBallTask extends TimerTask {
   Ball myBall;

   public void run() {
       //calculate the new position of myBall
   }
}

और फिर कुछ अद्यतन अंतराल के साथ नए कार्य को टाइमर में जोड़ें

final int FPS = 40;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000/FPS);

अस्वीकरण: यह आदर्श समाधान नहीं है। यह टाइमर क्लास (जैसा कि ओपी द्वारा पूछा गया है) का उपयोग करके समाधान है। एंड्रॉइड एसडीके में, हैंडलर क्लास का उपयोग करने की सिफारिश की गई है (स्वीकृत उत्तर में उदाहरण है)।


1
यदि आप ऊपर की पोस्ट पढ़ते हैं, तो आप देखेंगे कि यह एक आदर्श समाधान क्यों नहीं है
डेव.बी

2
बेशक। ओपी इसे टाइमरके साथ करना चाहता था, जिसे मैं खेल में इस्तेमाल करने की सलाह नहीं दूंगा।
फिक्शन

3
है ना? ओपी ने यह नहीं बताया कि वे इसे कैसे चाहते हैं। वे एक लेख से जुड़े थे जो टिमरस्कैस का उपयोग करता था, लेकिन उन्होंने यह अनुरोध नहीं किया कि इसे इस तरह से किया जाए।
टूलमेकरसैट

1
बहुत मदद की, धन्यवाद @fiction
नावेद अहमद

1
महान जवाब सरल का पालन करें।
JMASTER B

64

अगर आपको यूआई थ्रेड पर अपना कोड चलाने की आवश्यकता है (और टाइमर थ्रेड पर नहीं), तो ब्लॉग पर एक नज़र डालें: http://steve.odyfamily.com/?p=12

public class myActivity extends Activity {
private Timer myTimer;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    myTimer = new Timer();
    myTimer.schedule(new TimerTask() {          
        @Override
        public void run() {
            TimerMethod();
        }

    }, 0, 1000);
}

private void TimerMethod()
{
    //This method is called directly by the timer
    //and runs in the same thread as the timer.

    //We call the method that will work with the UI
    //through the runOnUiThread method.
    this.runOnUiThread(Timer_Tick);
}


private Runnable Timer_Tick = new Runnable() {
    public void run() {

    //This method runs in the same thread as the UI.               

    //Do something to the UI thread here

    }
};
}

पूर्णता की खातिर आप शायद उल्लेख कर सकते हैं कि टाइमर को रोकने के लिए क्या करना है, और शायद इसे पुनरारंभ करें। (मुझे यहाँ आवश्यक जानकारी मिली: stackoverflow.com/questions/11550561/… )
RenniePet

3
क्या कोई कारण नहीं है कि आप सिर्फ सीधे RunerUIThread को TimerTask रन विधि से कॉल कर सकते हैं? ठीक काम करने लगता है और घोंसले के एक और स्तर को हटा देता है।
रिची एचएच

निश्चित रूप से, यह सभी चरणों को समझने के लिए केवल एक सिद्धांत है। मेरा सुझाव है कि इस मानक के पास एक पठनीय कोड है।
मीर गेरेनस्टैड

41

एक बस रास्ते के अंतराल पर नियमित रूप से सूचनाओं के साथ भविष्य में एक समय तक के लिए उलटी गिनती समय निर्धारित करना चाहते हैं, तो आप उपयोग कर सकते हैं CountDownTimer वर्ग कि एपीआई स्तर 1 के बाद से उपलब्ध है।

new CountDownTimer(30000, 1000) {
    public void onTick(long millisUntilFinished) {
        editText.setText("Seconds remaining: " + millisUntilFinished / 1000);
    }

    public void onFinish() {
        editText.setText("Done");
    }
}.start();

2
CountDownTimer केवल तभी समझ में आता है जब आप जानते हैं कि आप चाहते हैं कि यह कई निष्पादन के बाद दूर हो जाए। यह एक विशिष्ट और न ही विशेष रूप से लचीला, दृष्टिकोण नहीं है। अधिक सामान्य वह टाइमर है जो हमेशा के लिए दोहराता है (जिसे आप अब आवश्यकता नहीं होने पर रद्द करते हैं), या हैंडलर जो एक बार चलता है, और फिर स्वयं को फिर से शुरू करता है यदि फिर से आवश्यकता होगी। अन्य उत्तर देखें।
ToolmakerSteve

1
तुम पूर्ण रूप से सही हो। वर्ग के नाम से यह एक समय तक टाइमर टिक टिक प्रदान करता है जब तक कि खत्म नहीं हो जाता है और निश्चित रूप से यह इसके कार्यान्वयन में हैंडलर का उपयोग करता है।
अहमद हेगाज़ी

मिलीसेकंड भी कैसे दिखाएं? प्रारूप में SS:MiMi? धन्यवाद
रूचिर Baronia

26

यह एक टाइमर के लिए कुछ सरल कोड है:

Timer timer = new Timer();
TimerTask t = new TimerTask() {       
    @Override
    public void run() {

        System.out.println("1");
    }
};
timer.scheduleAtFixedRate(t,1000,1000);

12

मुझे लगता है कि आप इसे Rx तरह से कर सकते हैं:

 timerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                      //TODO do your stuff
                }
            });

और इसे रद्द करें:

timerSubscribe.unsubscribe();

आरएक्स टाइमर http://reactivex.io/documentation/operators/timer.html


10

क्योंकि यह प्रश्न अभी भी Google खोज (एंड्रॉइड टाइमर के बारे में) के बहुत से उपयोगकर्ताओं को आकर्षित कर रहा है, मैं अपने दो सिक्के डालना चाहूंगा।

सबसे पहले, टाइमर कक्षा को जावा 9 में पदावनत किया जाएगा (स्वीकृत उत्तर पढ़ें)

आधिकारिक सुझाव दिया तरीके से उपयोग करने के लिए है ScheduledThreadPoolExecutor जो अधिक प्रभावी है और सुविधाओं से भरपूर है कि इसके साथ ही एक दिया विलंब के बाद चलाने के लिए अनुसूची आदेशों सकते हैं, या समय-समय पर निष्पादित करने के लिए। साथ ही, यह थ्रेडपूल एक्सकॉक्टर की अतिरिक्त लचीलापन और क्षमता देता है।

यहाँ सादी कार्यात्मकताओं का उपयोग करने का एक उदाहरण है।

  1. निष्पादक सेवा बनाएँ:

    final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
  2. बस आप चलने योग्य अनुसूची:

    final Future<?> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
  3. अब आप futureकार्य को रद्द करने के लिए उपयोग कर सकते हैं या जाँच कर सकते हैं कि क्या यह उदाहरण के लिए किया गया है:

    future.isDone();

आशा है कि आपको एंड्रॉइड में एक कार्य बनाने के लिए यह उपयोगी मिलेगा।

पूरा उदाहरण:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Future<?> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
if (sampleFutureTimer.isDone()){
    // Do something which will save world.
}

8

मुझे आश्चर्य है कि कोई जवाब नहीं है जो RxJava2 के साथ समाधान का उल्लेख करेगा । यह वास्तव में सरल है और एंड्रॉइड में टाइमर सेटअप करने का एक आसान तरीका प्रदान करता है।

पहले आपको ग्रेडल निर्भरता की स्थापना करने की आवश्यकता है, अगर आपने ऐसा पहले से नहीं किया है:

implementation "io.reactivex.rxjava2:rxjava:2.x.y"

(की जगह xऔर yसाथ वर्तमान संस्करण संख्या )

चूँकि हमारे पास सिर्फ एक सरल, गैर-दोहराव वाला काम है , हम Completableवस्तु का उपयोग कर सकते हैं :

Completable.timer(2, TimeUnit.SECONDS, Schedulers.computation())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(() -> {
            // Timer finished, do something...
        });

दोहराए जाने के लिए , आप Observableएक समान तरीके से उपयोग कर सकते हैं :

Observable.interval(2, TimeUnit.SECONDS, Schedulers.computation())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(tick -> {
            // called every 2 seconds, do something...
        }, throwable -> {
            // handle error
        });

Schedulers.computation()यह सुनिश्चित करता है कि हमारा टाइमर बैकग्राउंड थ्रेड पर चल रहा है और .observeOn(AndroidSchedulers.mainThread())कोड का मतलब है कि हम टाइमर खत्म होने के बाद रन करेंगे।

अवांछित स्मृति लीक से बचने के लिए, आपको गतिविधि / फ़्रैगमेंट नष्ट होने पर सदस्यता समाप्त करना सुनिश्चित करना चाहिए।


4
यह सबसे साफ तरीका है!
कांस्टेंटिन

कोई इनको कैसे रद्द करता है? जब उपयोगकर्ता यूआई पर [STOP] बटन दबाता है और निष्पादित करने से पहले कम्प्लीटटेबल रद्द हो जाता है।
कोई व्यक्ति

@SomeoneSomewhere चर में विधि Subscriptionद्वारा लौटे को बचाएं .subscribe()और फिर subscription.unsubscribe()टाइमर को बंद करने के लिए कॉल करें ।
मिकेर

2

वह सरल समाधान है, मेरे ऐप में ठीक काम करता है।

  public class MyActivity extends Acitivity {

    TextView myTextView;
    boolean someCondition=true;

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.my_activity);

            myTextView = (TextView) findViewById(R.id.refreshing_field);

            //starting our task which update textview every 1000 ms
            new RefreshTask().execute();



        }

    //class which updates our textview every second

    class RefreshTask extends AsyncTask {

            @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                String text = String.valueOf(System.currentTimeMillis());
                myTextView.setText(text);

            }

            @Override
            protected Object doInBackground(Object... params) {
                while(someCondition) {
                    try {
                        //sleep for 1s in background...
                        Thread.sleep(1000);
                        //and update textview in ui thread
                        publishProgress();
                    } catch (InterruptedException e) {
                        e.printStackTrace(); 

                };
                return null;
            }
        }
    }

2

आप चाहते हैं कि आपका UI अपडेट पहले से मौजूद UI थ्रेड में हो।

सबसे अच्छा तरीका एक हैंडलर का उपयोग करना है जो देरी के बाद एक रननेबल को चलाने के लिए पोस्टडेलिड का उपयोग करता है (प्रत्येक रन अगले शेड्यूल करता है); हटाएं कॉलबैक के साथ कॉलबैक साफ़ करें।

आप पहले से ही सही जगह देख रहे हैं, इसलिए इसे फिर से देखें, शायद स्पष्ट करें कि कोड नमूना वह क्यों नहीं है जो आप चाहते हैं। ( टाइमर से यूआई को अपडेट करने पर समान लेख देखें )।


दुर्भाग्य से, आपका लिंक मर चुका है। मैं जल्दी से वापस सही लेख नहीं ढूँढ सकता।
लेकेन्स्टेयिन


1

यहाँ एक सरल विश्वसनीय तरीका है ...

अपनी गतिविधि में निम्न कोड डालें, और टिक () विधि को यूआई थ्रेड में हर सेकंड कहा जाएगा, जबकि आपकी गतिविधि "फिर से शुरू" स्थिति में है। बेशक, आप जो चाहते हैं उसे करने के लिए टिक () विधि को बदल सकते हैं, या कम या ज्यादा बार कहा जा सकता है।

@Override
public void onPause() {
    _handler = null;
    super.onPause();
}

private Handler _handler;

@Override
public void onResume() {
    super.onResume();
    _handler = new Handler();
    Runnable r = new Runnable() {
        public void run() {
            if (_handler == _h0) {
                tick();
                _handler.postDelayed(this, 1000);
            }
        }

        private final Handler _h0 = _handler;
    };
    r.run();
}

private void tick() {
    System.out.println("Tick " + System.currentTimeMillis());
}

रुचि रखने वालों के लिए, "_h0 = _handler" कोड आवश्यक है कि अगर आपकी गतिविधि रुकी हुई हो और टिक अवधि के भीतर फिर से शुरू हो जाए, तो दो टाइमर एक साथ चलने से बचें।


2
क्यों यह अजीब कर _h0के बजाय, दृष्टिकोण removeCallbacksमें onPauseहर किसी की तरह,?
टूलमेकरसिटेव

1

आप इसके लिए एक एनिमेटर का उपयोग भी कर सकते हैं:

int secondsToRun = 999;

ValueAnimator timer = ValueAnimator.ofInt(secondsToRun);
timer.setDuration(secondsToRun * 1000).setInterpolator(new LinearInterpolator());
timer.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
    {
        @Override
        public void onAnimationUpdate(ValueAnimator animation)
        {
            int elapsedSeconds = (int) animation.getAnimatedValue();
            int minutes = elapsedSeconds / 60;
            int seconds = elapsedSeconds % 60;

            textView.setText(String.format("%d:%02d", minutes, seconds));
        }
    });
timer.start();

0

आपको अपडेट लूप को संभालने के लिए एक थ्रेड बनाने की आवश्यकता है और इसे टेक्सारिया को अपडेट करने के लिए उपयोग करें। हालांकि मुश्किल हिस्सा यह है कि केवल मुख्य धागा वास्तव में यूआई को संशोधित कर सकता है ताकि अपडेट लूप थ्रेड को अपडेट करने के लिए मुख्य धागे को संकेत देने की आवश्यकता हो। यह एक हैंडलर का उपयोग करके किया जाता है।

इस लिंक को देखें: http://developer.android.com/guide/topics/ui/dialogs.html# "उदाहरण के लिए ProgressDialog with a second thread" शीर्षक वाले सेक्शन पर क्लिक करें। यह बिल्कुल एक उदाहरण है कि आपको टेक्स्ट फ़ील्ड के बजाय प्रगति संवाद के अलावा क्या करना चाहिए।


यह मत करो। एक साधारण टाइमर वर्ग है जो आपके लिए यह सब करता है। और इस सवाल का प्रोग्रेसिअलॉग्स या डायलॉग्स से बिल्कुल भी कोई लेना-देना नहीं है।
फाल्मरी

क्या आपने मेरे द्वारा पोस्ट किए गए लिंक के अनुभाग को देखा या आपने सिर्फ डायलॉग और मान लिया? वहाँ कोड 100% प्रासंगिक है। इसके अलावा FYI करें, यदि आप टाइमर का उपयोग करते हैं, तो आप अपडेट लूप को संभालने के लिए थ्रेड बना रहे हैं। आपको अभी भी मेरे द्वारा पोस्ट किए गए लिंक में वर्णित हैंडलर का उपयोग करना होगा।
निक

दुर्भाग्य से, लिंक किए गए पृष्ठ में अब उल्लिखित शीर्षक वाला एक खंड नहीं है। कोड से लिंक करते समय, किसी को हमेशा कुंजी स्निपेट को सीधे आपके उत्तर में शामिल करना चाहिए।
टूलमेकरसैट

0
void method(boolean u,int max)
{
    uu=u;
    maxi=max;
    if (uu==true)
    { 
        CountDownTimer uy = new CountDownTimer(maxi, 1000) 
  {
            public void onFinish()
            {
                text.setText("Finish"); 
            }

            @Override
            public void onTick(long l) {
                String currentTimeString=DateFormat.getTimeInstance().format(new Date());
                text.setText(currentTimeString);
            }
        }.start();
    }

    else{text.setText("Stop ");
}

2
शायद कुछ कोड इंडेंटेशन और कोड स्पष्टीकरण उपयोगी होंगे।
राउल रेने

0

अगर किसी को दिलचस्पी है, तो मैंने यूआई थ्रेड पर गतिविधियों को चलाने के लिए एक मानक ऑब्जेक्ट बनाने के साथ खेलना शुरू कर दिया। ठीक काम करने लगता है। टिप्पणियाँ स्वागत है। मुझे यह पसंद आएगा कि लेआउट डिजाइनर पर एक गतिविधि पर खींचने के लिए एक घटक के रूप में उपलब्ध हो। कुछ ऐसा नहीं मान सकते जो पहले से मौजूद नहीं है।

package com.example.util.timer;

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

import android.app.Activity;

public class ActivityTimer {

    private Activity m_Activity;
    private boolean m_Enabled;
    private Timer m_Timer;
    private long m_Delay;
    private long m_Period;
    private ActivityTimerListener m_Listener;
    private ActivityTimer _self;
    private boolean m_FireOnce;

    public ActivityTimer() {
        m_Delay = 0;
        m_Period = 100;
        m_Listener = null;
        m_FireOnce = false;
        _self = this;
    }

    public boolean isEnabled() {
        return m_Enabled;
    }

    public void setEnabled(boolean enabled) {
        if (m_Enabled == enabled)
            return;

        // Disable any existing timer before we enable a new one
        Disable();

        if (enabled) {
            Enable();
        }
    }

    private void Enable() {
        if (m_Enabled)
            return;

        m_Enabled = true;

        m_Timer = new Timer();
        if (m_FireOnce) {
            m_Timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    OnTick();
                }
            }, m_Delay);
        } else {
            m_Timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    OnTick();
                }
            }, m_Delay, m_Period);
        }
    }

    private void Disable() {
        if (!m_Enabled)
            return;

        m_Enabled = false;

        if (m_Timer == null)
            return;

        m_Timer.cancel();
        m_Timer.purge();
        m_Timer = null;
    }

    private void OnTick() {
        if (m_Activity != null && m_Listener != null) {
            m_Activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    m_Listener.OnTimerTick(m_Activity, _self);
                }
            });
        }
        if (m_FireOnce)
            Disable();
    }

    public long getDelay() {
        return m_Delay;
    }

    public void setDelay(long delay) {
        m_Delay = delay;
    }

    public long getPeriod() {
        return m_Period;
    }

    public void setPeriod(long period) {
        if (m_Period == period)
            return;
        m_Period = period;
    }

    public Activity getActivity() {
        return m_Activity;
    }

    public void setActivity(Activity activity) {
        if (m_Activity == activity)
            return;
        m_Activity = activity;
    }

    public ActivityTimerListener getActionListener() {
        return m_Listener;
    }

    public void setActionListener(ActivityTimerListener listener) {
        m_Listener = listener;
    }

    public void start() {
        if (m_Enabled)
            return;
        Enable();
    }

    public boolean isFireOnlyOnce() {
        return m_FireOnce;
    }

    public void setFireOnlyOnce(boolean fireOnce) {
        m_FireOnce = fireOnce;
    }
}

गतिविधि में, मेरे पास यह ऑनस्टार्ट है:

@Override
protected void onStart() {
    super.onStart();

    m_Timer = new ActivityTimer();
    m_Timer.setFireOnlyOnce(true);
    m_Timer.setActivity(this);
    m_Timer.setActionListener(this);
    m_Timer.setDelay(3000);
    m_Timer.start();
}

1
यार व्हाट्सएप गलत है एक्टिविटीटीमरलिस्ट? मेरे एडीटी बंडल ने कहा कि ऐसी कोई कक्षा नहीं है।
सोरोकिन एंड्री

0
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

 CheckBox optSingleShot;
 Button btnStart, btnCancel;
 TextView textCounter;

 Timer timer;
 MyTimerTask myTimerTask;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  optSingleShot = (CheckBox)findViewById(R.id.singleshot);
  btnStart = (Button)findViewById(R.id.start);
  btnCancel = (Button)findViewById(R.id.cancel);
  textCounter = (TextView)findViewById(R.id.counter);

  btnStart.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {

    if(timer != null){
     timer.cancel();
    }

    //re-schedule timer here
    //otherwise, IllegalStateException of
    //"TimerTask is scheduled already" 
    //will be thrown
    timer = new Timer();
    myTimerTask = new MyTimerTask();

    if(optSingleShot.isChecked()){
     //singleshot delay 1000 ms
     timer.schedule(myTimerTask, 1000);
    }else{
     //delay 1000ms, repeat in 5000ms
     timer.schedule(myTimerTask, 1000, 5000);
    }
   }});

  btnCancel.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    if (timer!=null){
     timer.cancel();
     timer = null;
    }
   }
  });

 }

 class MyTimerTask extends TimerTask {

  @Override
  public void run() {
   Calendar calendar = Calendar.getInstance();
   SimpleDateFormat simpleDateFormat = 
     new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
   final String strDate = simpleDateFormat.format(calendar.getTime());

   runOnUiThread(new Runnable(){

    @Override
    public void run() {
     textCounter.setText(strDate);
    }});
  }

 }

}

.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:autoLink="web"
    android:text="http://android-er.blogspot.com/"
    android:textStyle="bold" />
<CheckBox 
    android:id="@+id/singleshot"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Single Shot"/>


मैं देखता हूं कि आपने मूल प्रश्न और उत्तर के कई वर्षों बाद इसे जोड़ा है। कृपया यह विवरण जोड़ें कि यह उत्तर अन्य उत्तरों की तुलना कैसे करता है जो पहले से ही थे। आपने दूसरा क्यों जोड़ा - क्या लाभ / जब उपयोगी / क्या कमी आपने अन्य उत्तरों में देखी?
टूलमेकरसिटेव

मैं सिर्फ एक कोड साझा करता हूं जो एक अलग दृष्टिकोण के साथ एक ही काम कर रहा है। लेकिन जब भी आप किसी भी व्यू का डेटा अपडेट करना चाहते हैं। आपको इसके लिए हैंडलर का उपयोग करना चाहिए। क्योंकि कई बार मैंने नोटिस किया है कि किसी व्यू को अपडेट करने के लिए टाइमटेस्क का उपयोग करने से काम नहीं चलता है .. @ Dave.B विधि मेरे ज्ञान के लिए अधिक सही है।
ज़ार ई अहमर

0

यदि आपके पास पहले से ही डेल्टा समय है।

public class Timer {
    private float lastFrameChanged;
    private float frameDuration;
    private Runnable r;

    public Timer(float frameDuration, Runnable r) {
        this.frameDuration = frameDuration;
        this.lastFrameChanged = 0;
        this.r = r;
    }

    public void update(float dt) {
        lastFrameChanged += dt;

        if (lastFrameChanged > frameDuration) {
            lastFrameChanged = 0;
            r.run();
        }
    }
}

0

मैं सार टाइमर दूर और यह एक अलग वर्ग बना दिया:

Timer.java

import android.os.Handler;

public class Timer {

    IAction action;
    Handler timerHandler = new Handler();
    int delayMS = 1000;

    public Timer(IAction action, int delayMS) {
        this.action = action;
        this.delayMS = delayMS;
    }

    public Timer(IAction action) {
        this(action, 1000);
    }

    public Timer() {
        this(null);
    }

    Runnable timerRunnable = new Runnable() {

        @Override
        public void run() {
            if (action != null)
                action.Task();
            timerHandler.postDelayed(this, delayMS);
        }
    };

    public void start() {
        timerHandler.postDelayed(timerRunnable, 0);
    }

    public void stop() {
        timerHandler.removeCallbacks(timerRunnable);
    }
}

और मुख्य कार्रवाई को Timerकक्षा से बाहर निकालें

IAction.java

public interface IAction {
    void Task();
}

और मैंने इसे इस तरह इस्तेमाल किया:

MainActivity.java

public class MainActivity extends Activity implements IAction{
...
Timer timerClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
        ...
        timerClass = new Timer(this,1000);
        timerClass.start();
        ...
}
...
int i = 1;
@Override
public void Task() {
    runOnUiThread(new Runnable() {

        @Override
        public void run() {
            timer.setText(i + "");
            i++;
        }
    });
}
...
}

मुझे आशा है कि यह मदद करता है 😊👌


0

मैं इस तरह से उपयोग करता हूं:

String[] array={
       "man","for","think"
}; int j;

फिर ऑनक्रिएट के नीचे

TextView t = findViewById(R.id.textView);

    new CountDownTimer(5000,1000) {

        @Override
        public void onTick(long millisUntilFinished) {}

        @Override
        public void onFinish() {
            t.setText("I "+array[j] +" You");
            j++;
            if(j== array.length-1) j=0;
            start();
        }
    }.start();

यह इस समस्या को हल करने का आसान तरीका है।


0

उन लोगों के लिए जो क्रोनोमीटर पर भरोसा नहीं कर सकते हैं , मैंने सुझावों में से एक से उपयोगिता वर्ग बनाया:

public class TimerTextHelper implements Runnable {
   private final Handler handler = new Handler();
   private final TextView textView;
   private volatile long startTime;
   private volatile long elapsedTime;

   public TimerTextHelper(TextView textView) {
       this.textView = textView;
   }

   @Override
   public void run() {
       long millis = System.currentTimeMillis() - startTime;
       int seconds = (int) (millis / 1000);
       int minutes = seconds / 60;
       seconds = seconds % 60;

       textView.setText(String.format("%d:%02d", minutes, seconds));

       if (elapsedTime == -1) {
           handler.postDelayed(this, 500);
       }
   }

   public void start() {
       this.startTime = System.currentTimeMillis();
       this.elapsedTime = -1;
       handler.post(this);
   }

   public void stop() {
       this.elapsedTime = System.currentTimeMillis() - startTime;
       handler.removeCallbacks(this);
   }

   public long getElapsedTime() {
       return elapsedTime;
   }
 }

का उपयोग करने के लिए .. अन्याय करते हैं:

 TimerTextHelper timerTextHelper = new TimerTextHelper(textView);
 timerTextHelper.start();

.....

 timerTextHelper.stop();
 long elapsedTime = timerTextHelper.getElapsedTime();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.