2011-03-08 15 views
7

का उपयोग हैंडलर का उपयोग करने का बेहतर तरीका कौन सा है। कोई फायदे मेरे सामने आने वाले सभी उदाहरण इनलाइन संस्करण देने लगते हैं।हैंडलर एंड्रॉइड

कक्षा में कार्यान्वयन Handler.Callback और कार्यान्वयन इंटरफ़ेस विधि का उपयोग करना।

या

इनलाइन कोड संस्करण

private Handler mHandler = new Handler(){ ....}; 

उत्तर

5

आम शब्द या इन इनलाइन वर्ग परिभाषाओं बेनामी वर्ग है।

आप Java/Android: anonymous local classes vs named classes

में इन पर चर्चा के बारे में अधिक पढ़ सकते हैं अनिवार्य रूप से मुख्य अंतर readbility, कोडिंग की गति, पुनः उपयोग और गुंजाइश है।

एक संसाधन बिंदु से अज्ञात वर्ग निर्माण कचरा कलेक्टर में ओवरहेड का कारण बन सकता है जैसा कि Avoid Creating Unnecessary Objects में चर्चा की गई है। मैं अज्ञात वर्ग निर्माण के सटीक विवरणों पर निश्चित नहीं हूं, हालांकि, यह तार्किक है कि वर्ग पर इंटरफ़ेस को कार्यान्वित करना अधिक कुशल है।

@ विलियम टीमालर्ड ने का उदाहरण दिया है। उनके उदाहरण में, एक लंबे और वाक्य रचनात्मक जटिल हैंडलर को अज्ञात हैंडलर की बजाय कक्षा में कार्यान्वित किया जाना चाहिए क्योंकि इनलाइन परिभाषित करते समय इसे पढ़ना और संपादित करना कठिन होता है।

0

इस का उपयोग करते हुए वास्तव में ऊपर प्रश्न का उत्तर क्योंकि मैं नहीं जानता कि क्या "सबसे अच्छा तरीका है" नहीं है, और यह संभावना पर निर्भर करता है आप क्या कर रहे हैं। हालांकि, मैं समझाऊंगा कि मैं क्या कर रहा हूं और क्यों।

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

command = "Wake up!"; 

    mDeviceInterface.write(command, new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      switch(msg.what) { 
      case DeviceInterface.MESSAGE_TIMEOUT: // Process the timeout. 
       announce("Device not responding."); 
       break; 
      case DeviceInterface.MESSAGE_READ: // Process the response. 
       byte[] readBuf = (byte[]) msg.obj; 
       if (readBuf[0] == 0x05) { 
        // Success, update device status. 
       } else { 
        announce("Error!"); 
        break; 
       } 
      } 
     } 
    }); 

(। हमेशा याद रखें, यह शायद लायक आप इसके लिए वास्तव में क्या भुगतान किया है;))

2

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

package : android.os 
public class 
Handler 
extends Object 

एक हैंडलर आप भेजने के लिए और इस प्रक्रिया संदेश और एक थ्रेड MessageQueue के साथ जुड़े Runnable वस्तुओं की अनुमति देता है। प्रत्येक हैंडलर उदाहरण एक थ्रेड और उस थ्रेड के संदेश कतार से जुड़ा हुआ है। जब आप एक नया हैंडलर बनाते हैं, तो यह उस धागे के थ्रेड/संदेश कतार से जुड़ा होता है जो उस समय से बना रहा है - उस बिंदु से, यह संदेश संदेश और संदेश को उस संदेश कतार में वितरित करेगा और उन्हें संदेश से बाहर आने पर निष्पादित करेगा कतार।

एक हैंडलर के दो मुख्य उपयोग कर रहे हैं:

  1. संदेश और runnables शेड्यूल करने के लिए भविष्य में किसी समय के रूप में क्रियान्वित किया जा करने के लिए; और
  2. से अलग थ्रेड पर निष्पादित करने के लिए एक क्रिया को लागू करने के लिए।

उदाहरण के एप्लिकेशन छप पेज में 1

उपयोग हैंडलर।

if (!isFirstIn) { 
    mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS); 
} else { 
    mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS); 
} 


/************************************************************************************** 
*1. Handler 
*/ 
private Handler mHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(isAuto){ 
      switch (msg.what) { 
      case GO_HOME: 
       goHome(); 
       break; 
      case GO_GUIDE: 
       goGuide(); 
       break; 
      } 
     } 
     super.handleMessage(msg); 
    } 
}; 
private void goHome() { 
    Intent intent = new Intent(SplashActivity.this, MainAct.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

private void goGuide() { 
    Intent intent = new Intent(SplashActivity.this, GuideActivity.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

उदाहरण 2

बच्चे सूत्र में उपयोग हैंडलर अनुरोध नेटवर्क अनुरोध काम में समय लगता है हो सकता है यदि।

new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     String versionPath = Parameters.getCheckVersionPath(); 
     String result = RequestHelper.doGet(versionPath, null); 
     Message msg = new Message(); 
     Bundle data = new Bundle(); 
     data.putString("result",result); 
     msg.setData(data); 
     handler1.sendMessage(msg); 
    } 
}).start(); 

handler1 = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     String result = msg.getData().getString("result"); 
     JSONObject obj; 
     try { 
      obj = new JSONObject(result); 
      Map<String, String> versionInfo = Helper.getSoftwareVersion(obj); 
      if (versionInfo != null) { 
       newVersion = versionInfo.get("version"); 
       updateUrl = versionInfo.get("url"); 
      } 
     } catch (JSONException e) { 
      Log.w("net work error!", e); 
     } 
    } 

}; 

उदाहरण 3

उपयोग हैंडलर और टाइमर प्रगति बार अद्यतन करने के लिए।

logobar = (ImageView) findViewById(R.id.splash_bar);//progress bar. 
logobarClipe = (ClipDrawable) logobar.getBackground(); 

timer = new Timer(); 
timer.schedule(new TimerTask() { 
    public void run() { 
     updateLogoBarHandler.sendEmptyMessage(0); 
}}, 0, rate); 


/************************************************************************************** 
*2. Handler 
*/ 
//update progress bar. 
private Handler updateLogoBarHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(logobarClipe.getLevel() < 10000){ 
      //1.update image. 
      logobarClipe.setLevel(logobarClipe.getLevel() + rate*2); 

      //2.update text. 
      float percent = logobarClipe.getLevel() /100; 
      String percentTxtVerbose = String.valueOf(percent); 
      String percentTxt = percentTxtVerbose.substring(0, percentTxtVerbose.indexOf('.')) + "%"; 
      bartxt.setText(percentTxt); 

     }else{ 
      timer.cancel(); 
     } 
     super.handleMessage(msg); 
    } 
}; 
0

Android में अज्ञात कक्षाओं का उपयोग करने में एक खतरा है। this blog post में वर्णित है -

जावा में, गैर स्थिर भीतरी और अनाम कक्षाओं उनके बाहरी वर्ग के लिए एक अंतर्निहित संदर्भ पकड़ो।

और यहां एक रिसाव का अवसर आता है।

तो, संक्षिप्त उत्तर होगा: इंटरफ़ेस विधियों को लागू करें या स्थिर आंतरिक कक्षाओं का उपयोग करें (जिसमें बाहरी वर्ग संदर्भ नहीं है)।

उदाहरण के लिए, एक रिसाव सुरक्षित हैंडलर ऐसा दिखाई दे सकता:

private static class ChangeTextHandler extends Handler { 
    private final WeakReference activity; 

    public ChangeTextHandler(MainActivity activity) { 
     this.activity = new WeakReference<>(activity); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     MainActivity activity = this.activity.get(); 
     if (activity == null) { 
      Log.e(TAG, "Activity is null ChangeTextHandler.handleMessage()!"); 
      return; 
     } 

     final String text = (String) msg.getData().get(BUNDLE_KEY); 
     if (!TextUtils.isEmpty(text)) { 
      switch (msg.what) { 
       // do something 
      } 
     } 
    } 
} 

मैं एक blog post around usage of Handlers बनाया है, तो साथ ही जाँच :)

लायक हो सकता है
संबंधित मुद्दे