हर X सेकंड में एक विधि कैसे चलाएं


114

मैं एक Android 2.3.3 एप्लिकेशन विकसित कर रहा हूं और मुझे हर X सेकंड में एक विधि चलाने की आवश्यकता है ।

IOS में, मेरे पास NSTimer है , लेकिन Android में मुझे नहीं पता कि क्या उपयोग करना है।

किसी ने मुझे हैंडलर की सिफारिश की है ; एक और सलाह मुझे 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
"सबसे अच्छा एक" को परिभाषित करें। किस तरह से आप इसे सबसे अच्छा होना चाहते हैं?
साइमन फोर्सबर्ग

मुझे नहीं पता कि NSTimer के साथ कौन सा तरीका बेहतर है।
वंसफैनलाइन

@VansFannel कितने समय के अंतराल पर आप चाहते हैं?
फेमग्यू जुएल

मैंने इस प्रश्न को विवरण के साथ अद्यतन किया है कि मैं क्या करने की कोशिश कर रहा हूं।
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);विधि के माध्यम से पंजीकृत ईथर के लिए होना चाहिए। ब्रॉडकास्ट रिसीवर पर अधिक जानकारी के लिए कृपया आधिकारिक डॉक्स देखें। प्रसारण प्राप्तकर्ता

public class MyReceiver extends BroadcastReceiver{

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

अगर यह = <10minutes → मैं एक हैंडलर के साथ जाना होगा।

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

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

3
समय की देरी के आधार पर अलग-अलग सुझाव क्यों?
सिमोन फोर्सबर्ग

7
दक्षता, अलार्म मैनजर डॉक्स में यह कहा गया है कि इसका उपयोग किसी छोटे अंतराल के दोहराव वाले कार्य के लिए नहीं किया जाना चाहिए।
जुग

9
@ SimonAndréForsberg में अलार्म मैनजर डॉक्स यह बताता है कि हैंडलर शॉर्ट टिक्स के लिए उपयोग करने के लिए प्रीफ़र्ड और अधिक प्रभावी तरीका है: "नोट: अलार्म मैनेजर उन मामलों के लिए अभिप्रेत है, जहाँ आप एक विशिष्ट समय पर अपना एप्लिकेशन रन करना चाहते हैं, भले ही आप वर्तमान में आवेदन नहीं चल रहा है। सामान्य समय के संचालन (टिक, टाइमआउट, आदि) के लिए हैंडलर का उपयोग करना आसान और अधिक कुशल है। "
फाम्यग्यु जुएल

लेकिन, मुझे उसी गतिविधि में एक विधि चलाने की आवश्यकता है जिसने अलार्म मैनजर लॉन्च किया है। मैं उसे कैसे कर सकता हूँ?
VansFannel

2
@ahmadalibaloch रन करने योग्य के भीतर से आप कर सकते हैं h.removeCallbacks(this);, अन्यथा आपको इसे हटाने में सक्षम होने के लिए रननेबल का एक संदर्भ बनाए रखने की आवश्यकता है। यदि दूसरा वांछित है तो यहां पोस्ट की गई विधि आपका सबसे अच्छा मार्ग नहीं हो सकती है।
Jug6ernaut 13

101

हर दूसरे के लिए टाइमर का उपयोग करें ...

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 ) का उपयोग न करें , हैंडलर या शेड्यूल्ड ट्रेडपूल का उपयोग करें।
अप्पादेवो १५'१ at को

69

आप कृपया इस कोड को onResume () के माध्यम से हैंडलर को हर 15 सेकंड पर कॉल करने की कोशिश कर सकते हैं और जब गतिविधि दिखाई न दे, तो इसे ऑनपॉज़ () के माध्यम से रोक दें।

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
यह वही है जिसे मैं देख रहा था। उत्तम।
सांप

3
यह एकदम सही जवाब है!
रिद्धि

सटीक! TabLayout में MainActivity के मौजूदा चयनित टैब की जाँच करने के लिए उपयोग करना इस खंड से मेल खाता है और यदि काम बंद नहीं है - onPause () विफल रहता है जब कोई TabLayout चयनित टैब के दोनों ओर टैब चयनित करता है
BENN1TH

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

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. कॉलबैक के माध्यम से अपने डेटा को नियंत्रित करने के बजाय, आप डेटा की एक धारा बनाते हैं जिसे आप सदस्यता लेते हैं। यह "पोलिंग डेटा" लॉजिक और "यूआई को आपके डेटा के साथ लॉजिक" करने की चिंता को अलग करता है ताकि आप अपने "डेटा स्रोत" कोड और अपने यूआई कोड को न मिलाएं।
  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 की जाँच करें। इसमें एक उच्च सीखने की अवस्था है लेकिन यह एंड्रॉइड में अतुल्यकालिक कॉलिंग को इतना आसान और क्लीनर से निपटने में मदद करेगा।


4

कोटलिन के साथ, हम अब इसके लिए एक सामान्य कार्य कर सकते हैं!

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
केवल कोड का जवाब न दें। कृपया अपना उत्तर संपादित करें और कुछ स्पष्टीकरण जोड़ें।
शाशनथ

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

कृपया उस स्थिति का वर्णन करें जब मेरा उत्तर काम नहीं करेगा
उमर अता

नमस्कार उमर मुझे उस समय एक सर्कल की आवश्यकता थी जब वह ऐप जीवित हो, गतिविधि के जीवित रहने के दौरान हैंडलर ने पुनरावृत्ति को जीवित कर दिया लेकिन मुझे सर्कल की आवश्यकता है जबकि मैं अन्य गतिविधियों का भी दौरा करने में सक्षम था। तो धागा इस तरह से समाधान है यकीन है कि यह भी अपने संघर्ष है।
सैम

1

यहाँ शायद आपकी समस्या के लिए Rx Java और Rx Android का उपयोग करके उपयोगी उत्तर दिया गया है

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