2011-09-04 15 views
5

मुझे किसी सेवा से मुख्य गतिविधि का संदर्भ प्राप्त करने की आवश्यकता है।किसी सेवा से गतिविधि का संदर्भ प्राप्त करें

यह मेरा डिजाइन है:

MainActivity.java

public class MainActivity extendsActivity{ 
private Intent myIntent; 
onCreate(){ 
myIntent=new Intent(MainActivity.this, MyService.class); 

btnStart.setOnClickListener(new OnClickListener(){ 
    public void onClick(View V){ 
    startService(myIntent); 
    }); 
}} 

MyService.java

class MyService extends Service{ 

public IBinder onBind(Intent intent) { 
    return null; 
} 

onCreate(){ 
//Here I need to have a MainActivity reference 
//to pass it to another object 
} 
} 

मैं ऐसा कैसे कर सकते हैं?

[संपादित करें]

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

InputStream iS =myActivity.getAssets().open("www/"+filename); 

और कोई सेवाओं, इसलिए मैं मुख्य गतिविधि के संदर्भ सीधे से ही पारित कर सकते हैं:

WebServer ws= new DroidWebServer(8080,this); 

तो, आदेश में इस एप्लिकेशन को एक सेवा के साथ काम करता है बनाने के लिए, क्या मैं अपने डिजाइन में बदलना चाहिए?

उत्तर

7

आप की व्याख्या नहीं की थी कि आप इस की जरूरत है। लेकिन यह निश्चित रूप से खराब डिज़ाइन है। गतिविधि के संदर्भों को संग्रहीत करना पहली बात है कि आप गतिविधियों के साथ नहीं करना चाहिए। खैर, आप कर सकते हैं, लेकिन आपको गतिविधि जीवन चक्र को ट्रैक करना होगा और इसके onDestroy() के बाद संदर्भ जारी करना होगा। यदि आप ऐसा नहीं कर रहे हैं, तो आपको एक स्मृति रिसाव मिलेगी (जब कॉन्फ़िगरेशन बदलता है, उदाहरण के लिए)। और, ठीक है, onDestroy() के बाद, गतिविधि को मृत माना जाता है और वैसे भी बेकार है।

तो बस सेवा में संदर्भ संग्रहीत न करें। वर्णन करें कि आपको इसके बजाय क्या हासिल करने की आवश्यकता है। मुझे यकीन है कि वहाँ बेहतर विकल्प हैं।


अद्यतन

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

मान लें कि आप एक अलग वर्ग है कि WebService अनुरोध संभालती है:

class WebService 
{ 
    private final Context mContext; 
    public WebService(Context ctx) 
    { 
     //The only context that is safe to keep without tracking its lifetime 
     //is application context. Activity context and Service context can expire 
     //and we do not want to keep reference to them and prevent 
     //GC from recycling the memory. 
     mContext = ctx.getApplicationContext(); 
    } 

    public void someFunc(String filename) throws IOException 
    { 
     InputStream iS = mContext.getAssets().open("www/"+filename); 
    } 
} 

अब आप Service से & उपयोग WebService उदाहरण बना सकते हैं (जो इस प्रकार की पृष्ठभूमि कार्य के लिए सिफारिश की है) या Activity भी से (जो बहुत जटिल काम है वेब सेवा कॉल या लंबे पृष्ठभूमि कार्यों में शामिल होने पर सही होने के लिए)।

एक उदाहरण Service साथ:

class MyService extends Service 
{ 
    WebService mWs; 
    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     mWs = new WebService(this); 

     //you now can call mWs.someFunc() in separate thread to load data from assets. 
    } 

    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return null; 
    } 
} 
+0

मैंने प्रश्न संपादित किया! – supergiox

+1

मैंने उत्तर – inazaruk

+0

अद्यतन किया है धन्यवाद! ऐसा लगता है कि गतिविधि की आवश्यकता वाले किसी विधि को छोड़कर, ठीक है, 'अंतिम कर्सर फोटो = गतिविधि .managedQuery (डेटा। कोंटिफुरि, नई स्ट्रिंग [] {फोटो.पीएचओटीओ}, डेटा._आईडी + "=?", नया स्ट्रिंग [ ] {photoId}, शून्य); ' – supergiox

2

आपकी सेवा और गतिविधि के बीच संवाद करने के लिए आपको एआईडीएल का उपयोग करना चाहिए। इस लिंक पर अधिक जानकारी:

संपादित करें: (धन्यवाद Renan Malke Stigliani) http://developer.android.com/guide/components/aidl.html

+0

क्या आप "सेवा और गतिविधि के बीच" मतलब है? – supergiox

+0

क्षमा करें। बेशक मैंने किया :) मैं अपना जवाब संपादित करूंगा। धन्यवाद – IncrediApp

+0

ठीक है :) उत्तर के लिए धन्यवाद! – supergiox

0

inazaruk की टिप्पणियों से सहमत हूँ। लेकिन, किसी गतिविधि और सेवा के बीच संचार करने के मामले में, आपके पास कुछ विकल्प हैं - एआईडीएल (जैसा ऊपर बताया गया है), मैसेंजर, ब्रॉडकास्ट रिसाइवर आदि। मैसेंजर विधि एआईडीएल के समान है लेकिन आपको इंटरफेस को परिभाषित करने की आवश्यकता नहीं है। आप यहाँ शुरू कर सकते हैं:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html

2

AIDL है overkill जब तक गतिविधि और सेवा अलग apks में हैं।

बस स्थानीय सेवा के लिए एक बाइंडर का उपयोग करें। (पूर्ण उदाहरण यहाँ: http://developer.android.com/reference/android/app/Service.html)

public class LocalBinder extends Binder { 
     LocalService getService() { 
      return LocalService.this; 
     } 
    } 
+1

यह आपको ओपी पूछने के लिए कैसे अनुमति देता है? यदि आप अधिक कोड उदाहरण के साथ संपादित करते हैं तो मैं ऊपर हट जाऊंगा। –

संबंधित मुद्दे