Event Handling in Android – उपरोक्त Discussion के माध्यम से हमने Event Handling को काफी आम भाषा में समझाने का प्रयास किया है लेकिन एक Programmer के रूप में जब तक आप इस Event Handling Mechanism को Programming की Technical भाषा में नहीं समझते, तब तक आप वास्तव में ठीक से नहीं समझ पाते कि Java के अन्तर्गत की जाने वाली Event Driven Programming की Event Handling आखिर होती कैसे है। अन्य शब्दों में कहें तो-
- Events Fire होने का क्या मतलब है?
- Event Listener द्वारा उन Fired Events को Capture करने, Listen करने अथवा Notify होने का क्या मतलब है?
- Callback Event Handler Method के माध्यम से Event को Response करने का क्या मतलब है?
जब तक आप इन सवालों का Technical Answer नहीं जानते, Java की Event Handling आपके लिए एक अजूबा ही होती है और आपको हमेंशा Event Handling से सम्बंधित Rules को रटकर याद रखना पड़ता है। जबकि यदि आप Java के Event Handling Mechinsm की Internal Working को ठीक से समझ लें, तो फिर आपको Event Handling से सम्बंधित किसी भी Syntax को याद रखने की जरूरत नहीं रह जाती क्योंकि आप अपना Event Handling से सम्बंधित Java Codes Create करते समय ही अच्छी तरह से जानते हैं कि आप कौनसा Java Code क्यों लिख रहे हैं और उसका Event Handling के संदर्भ में Internally क्या Effect होगा।
वास्तव में Java और C# दोनों का Event Handling Mechanism लगभग एक समान ही है। इसके अन्तर्गत जब भी किसी Application में कोई Event होता है, तो उस Event को Represent करने के लिए JRE या .NET Framework में पहले से Defined कोई Specific Method Execute हो जाता है।
उदाहरण के लिए जब User किसी Button को Click करता है, तो Click() या इसी से मिलते-जुलते नाम का कोई Method Execute हो जाता है और इस Method के Execute हो जाने की प्रक्रिया को ही Event Fire होना या Event Trigger होना कहते हैं।
इस Trigger होने वाले Event को Response करने के लिए इसे Fire करने वाले Object या UI View Control को किसी न किसी Event Listener Class से Bind किया जाता है, जैसाकि पिछले Example में setOnClickListener() Method द्वारा ClickHandler Class के एक Anonymous Object के माध्यम से Button Control को ClickHandler Class के साथ Bind या Register किया गया था।
Event Fire करने वाले Event Source UI View Control के Event Listener के साथ Registration की इस प्रक्रिया द्वारा वास्तव में Listener Class के Callback Method का Reference उस UI View Control के Fire होने वाले Event() Method में Pass कर दिया जाता है।
परिणामस्वरूप Event Source द्वारा जैसे ही कोई Event Fire होता है, यानी कोई Event() Method Execute होता है, तो वह Event Method, Reference के रूप में आने वाले Callback Method को Invoke कर देता है जो कि Event Listener Class में Fire होने वाले Event को Response करने के लिए Implement किया गया है।
अब यदि इस प्रक्रिया को हम हमारे पिछले Example के आधार पर समझें, तो जैसे ही किसी Button पर Click किया जाता है, Click() Method Execute होता है, जिसे Click Event Fire होना कहते हैं।
जबकि Buttons को ClickHandler Listener Class के साथ Register करने की वजह से ClickHandler Class में Implement किए गए onClick() नाम के Callback Event Handler Method का Reference, Button के Click() Method को Pass हो जाता है। इसलिए जैसे ही Button का Click() Event Fire होता है, वह उस Reference के माध्यम से ClickHandler Listener Class के onClick() Method को Invoke कर देता है।
Button के Click() Event Method द्वारा ClickHandler Listener Class के इस onClick() Callback Method के Invoke होने की प्रक्रिया को ही Listener Class का Fired Event को Listen करना या Fired Event से Notify होना कहलाता है।
इसलिए Event Listener Class का Event को Listen करना या Event से Notify होना और UI View Control द्वारा किसी Fired Event को Response करने के रूप में किसी Callback Event Handler Method का Execute होना, दोनों एक ही प्रक्रिया के दो अलग नाम हैं और दोनों प्रक्रियाऐं अलग-अलग नहीं बल्कि एक ही समय पर और एक समान होती हैं।
इसलिए वास्तव में जब हम Java के Event Handling Mechnism की बात करते हैं, तो इसमें तीन नहीं बल्कि केवल दो ही Concepts होते हैं जिन्हें समझना व Setup करना होता है-
- वह UI View Control जो कि किसी Event को Fire करेगा और (Event Source)
- वह Event Listener जिसमें उस Fired Event को Handle करने के लिए Appropriate Event Handler Interface को Implement किया गया होगा यानी Appropriate Callback Event Handler Method को Define किया गया होगा। (Event Listener)
जबकि तीसरे Concept के रूप में हम उस Method या Mechanism को मान सकते हैं, जो Event Source व Callback Event Handler Method की Event Listener Class के बीच Binding Associate करता है।
विभिन्न Buttons को ClickHandler नाम के Event Listener के साथ Register करके Underlying Android System को इस बात का Instruction देने के बाद कि Current Activity के सभी Buttons के Click Events को ClickHandler नाम के Event Listener Class द्वारा ही Handle किया जाएगा, अब हमें ClickHandler Event Listener Class को Define करना होता है।
चूंकि Current Example में हम केवल विभिन्न Buttons के Click Event को ही ClickHandler Listener Class द्वारा Handle करना चाहते हैं, इसलिए हमने केवल setOnClickListener() Method के माध्यम से विभिन्न Button Controls को ClickHandler Listener Class के साथ Register किया है। लेकिन यदि हमें इन्हीं Buttons के किसी और Event को भी Handle करना हो, उदाहरण के लिए यदि हमें Buttons के लिए LongClick Event को भी Handle करना हो, तो उस स्थिति में हमें Buttons को निम्नानुसार setOnLongClickListener() Method के माध्यम से उस Event Listener Class से Register करना जरूरी होता है, जिसमें View.OnLongClickListener Interface को Implement किया गया हो-
findViewById(R.id.btnAdd).setOnLongClickListener(new ClickHandler());
findViewById(R.id.btnSub). setOnLongClickListener(new ClickHandler());
findViewById(R.id.btnMul). setOnLongClickListener(new ClickHandler());
findViewById(R.id.btnDiv). setOnLongClickListener(new ClickHandler());
findViewById(R.id.btnRem). setOnLongClickListener(new ClickHandler());
जरूरी नहीं है कि Different Interfaces को Implement करने के लिए हम Different Listener Classes Define करें, बल्कि हम ClickHandler Listener Class में View.OnClickListener Interface के साथ ही View.OnLongClickListener Interface को भी Implement कर सकते हैं क्योंकि यद्धपि Java हमें एक ही Class में Multiple Classes को Inherit करने की सुविधा नहीं देता, लेकिन हम एक ही Java Class में Multiple Interfaces को Implement कर सकते हैं। जैसे-
private class ClickHandler implements View.OnClickListener, View.OnLongClickListener {
. . .
}
चूंकि Java Interface एक प्रकार की Abstract Class होते हैं, जिसमें Declare किए गए सभी Methods को उस Class में Define करना जरूरी होता है, जिसमें उसे Implement किया गया हो, इसीलिए जब हम ClickHanedler Class में View.OnClickListener Interface को निम्नानुसार Implement करते हैं, तो हमें इसमें Declared प्रत्येक Method को Define करना जरूरी होता है।
लेकिन इस Interface में onClick() नाम का केवल एक ही Method है, जो कि एक Callback Event Handler Method है और उस समय Automatically Execute हो जाता है जब User, इसकी Listener Class के साथ Registered UI View Control को Click करता है, इसलिए ClickHandler Listener Class व इसके इकलौते onClick() Callback Method को निम्नानुसार Specify किया है-
private class ClickHandler implements View.OnClickListener {
public void onClick(View btnClicked) {
. . .
}
}
चूंकि ClickHandler नाम की हमारी Event Listener Class एक Inner Class, Member Class या Nested Class है और इस Class का Current Activity के बाहर कोई उपयोग नहीं है, इसीलिए इस Class को हमने private Access Specifier के साथ Specify किया है। लेकिन onClick() Method को public Access Specifier के साथ Specify किया है ताकि Current Class के Parent Class के Members इसे Access कर सकें। ये एक Default Callback Event Handler Method Declaration Syntax और हमें प्रत्येक Callback Method को Implement करते समय हमेंशा इसी तरीके को Use करना होता है।
Callback Event Handler Method में हमेंशा Parameter के रूप में एक View Object का Reference Pass होता है। इस View Object में उस UI View Control का Reference Pass होता है, जिसने Event Trigger किया है।
अत: यदि हम हमारे Example में देखें, तो btnClicked नाम के इस View Class के Reference में हमेंशा उस UI View Control का Reference Store होता है, जिस पर User ने Click किया है। इसी वजह से हम एक ही onClick() Event Handler द्वारा Current Activity पर Placed विभिन्न UI View Controls में से किस UI Control द्वारा Click Event Fire हुआ है, इस बात का आसानी से पता लगा सकते हैं और Appropriate Response दे सकते हैं।
अब यदि हम थोड़ा और आगे बढ़ें और onClick() Method के Implementation को देखें, तो सबसे पहले हमने निम्नानुसार etFN व etSN नाम के दो EditText व tvResult नाम का एक TextView Object Create किया है और तीनों द्वारा Current Activity के Layout में स्थित etFN, etSN व tvResult नाम के ID वाले Objects को Reference किया है-
// Get a reference to the etFN EditText of Layout
EditText etFN = (EditText) findViewById(R.id.etFN);
// Get a reference to the etSN EditText of Layout
EditText etSN = (EditText) findViewById(R.id.etSN);
// Get a reference to the tvResult TextView of Layout
TextView tvResult = (TextView) findViewById(R.id.tvResult);
यानी सबसे पहले हमने सबसे पहले Statement में findViewById() Method द्वारा उस UI View Control का Reference प्राप्त किया है जिसका Layout ID R.id.etFN है। अब चूंकि इस Layout ID वाला UI View Control एक EditText Class का Object है और Java, Type Casting के मामले में बहुत ही Strict है, इसलिए R.id.etFN Layout ID वाले Object के Reference को किसी EditText Type के Object में ही Hold किया जा सकता है जबकि स्वयं R.id.etFN एक प्रकार का Integer मान है। इसलिए सबसे पहले इसी Integer Type के Layout ID को निम्नानुसार Type Cast करके EditText Type में Convert किया गया है-
EditText etFN = (EditText) findViewById(R.id.etFN);
जब एक बार Layout ID का Type Casting, EditText Type के रूप में हो जाता है, तो उसके बाद इस EditText Type के Reference को Hold करने के लिए EditText Type के Object की ही जरूरत होती है। इसीलिए उपरोक्त Statement द्वारा EditText Type में Casted R.id.etFN Layout ID वाले EditText के Reference को etFN में Hold कर लिया जाता है।
परिणामस्वरूप activity_main.xml Layout File में Specified etFN ID वाले EditText Control को MainActivity.java में भी etFN नाम से ही Access and Manipulate किया जाना सम्भव हो जाता है लेकिन यहां ध्यान रखने वाली एक सबसे महत्वपूर्ण बात ये है कि R.id.etFN उस EditText UI View Control का ID है, जिसे activity_main.xml नाम की Layout File में Specify किया गया है, जबकि etFN EditText Type का वह Object है, जिसे MainActivity.java File में Declare किया गया है।
हालांकि इस Java File में Create किए गए etFN Object में भी activity_main.xml File में Specified R.id.etFN Layout ID वाले EditText View Object का ही Reference Stored है इसलिए etFN Object भी वास्तव में activity_main.xml File में R.id.etFN ID वाले EditText View Object को ही Java Codes के माध्यम से Reference करने की सुविधा Provide कर रहा है।
जिस तरह से हमने etFN Object के माध्यम से R.id.etFN Layout ID वाले EditText के Reference को Current Java File में प्राप्त कर लिया है ताकि हम Java Codes के माध्यम से इन Layout Objects के मानों को Dynamically Access and Manipulate कर सकें, ठीक उसी तरह से हमने अगले दोनों Statements द्वारा etSN व tvResult Objects में भी क्रमश: R.id.etSN व R.id.tvResult Layout ID वाले EditText व TextView Controls का Reference प्राप्त कर लिया है ताकि Java Codes द्वारा इन Layout View Controls के मानों को भी Dynamically Access and Manipulate किया जा सके।
अपने Current Android App के XML Layout से सम्बंधित UI Controls का Reference, अपनी Java File में प्राप्त कर लेने के बाद अब हमें इन्हीं References के माध्यम से User द्वारा इन UI Controls में Input किए जाने वाले मानों को Access करना होता है ताकि हम उन पर Appropriate Operations Perform करके कोई Calculated Result Generate कर सकें।
इस जरूरत को पूरा करने के लिए ही हमने निम्नानुसार fn व sn नाम के double Data Type के दो Variables Create किए हैं। इनमें XML Layout के R.id.etFN व R.id.etSN Layout ID वाले EditText View Controls में Input किए गए मानों को प्राप्त किया जाना है, जिनका Reference etFN व etSN Objects में Stored है।
चूंकि etFN व etSN EditText Controls में Input किया जाने वाला मान एक प्रकार का Text Content होता है, इसलिए सबसे पहले हमें अपनी Java File में इसी Text Content को Access करना होता है और किसी EditText Object में Input किए गए Text Content को अपनी Java File में Access करने के लिए EditText Class हमें getText() नाम का Methdod Provide करता है।
यानी User ने etFN व etSN EditText Objects में जो भी मान Input किया होता है, उसे अपनी Java File में Access करने के लिए हम etFN.getText() व etSN.getText() Statement Use कर सकते हैं।
हालांकि etFN व etSN EditText Objects में User द्वारा Numerical Values को Input किया जाता है और ये दोनों Statements उन्हीं Numerical Values को ही Return करते हैं, लेकिन क्योंकि इन Numerical Values को EditText Type के Object में Input किया गया होता है, इसलिए जब getText() Method के माध्यम से इन EditText UI Controls के Data को Return किया जाता है, तब Return होने वाले ये Numerical मान भी पूरी तरह से Text Content के रूप में ही Return होते हैं और Text Content पर किसी तरह का कोई Arithmetical Operation Perform नहीं किया जा सकता।
इसलिए User द्वारा Input किए गए Numerical मान जो कि getText() Method Use करने के कारण हमारी Java File में एक Text Content के रूप में प्राप्त होते हैं, को ऐसी Value में Convert करना जरूरी होता है, ताकि उस पर Arithmetical Operations Perform किए जा सकें और इस जरूरत को पूरा करने के लिए हम Java के Double.parseDouble() Method को Use कर सकते हैं।
लेकिन Double.parseDouble() Method Parameter के रूप में केवल String Value को ही Accept करता है जबकि etFN.getText() व etSN.getText() Statement जो मान Return करते हैं, वो Text Type का मान होते हैं। इसलिए इन Statements द्वारा Return होने वाले Text Content को Double.parseDouble() Method में Pass करने से पहले उन्हें String Format में Convert करना जरूरी है और इस जरूरत को पूरा करने के लिए हमें etFN.getText() व etSN.getText() Method द्वारा Return होने वाले मान के साथ निम्नानुसार toString() Method को Add किया है-
etFN.getText().toString()
किसी Method को इस तरह से Call करने की प्रक्रिया को Method Chaining के नाम से जाना जाता है जिसके अन्तर्गत पहले Method द्वारा Return मान के लिए सीधे ही दूसरा Method Invoke कर लिया जाता है। Methods को इस तरह से Chain के रूप में Call किया जाना पूरी तरह से Valid है और इसे समझने के लिए Programming के कुछ Internal Working को समझना जरूरी है।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook Android in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी है, तो निश्चित रूप से ये EBook भी आपके लिए काफी उपयोगी साबित होगी।
Android in Hindi | Page: 628 | Format: PDF