2016-05-23 18 views
15

तो एंड्रॉइड में मैं अपनी एप्लिकेशन क्लास को सिंगलटन बनाना चाहता हूं।कोटलिन सिंगलटॉन एप्लिकेशन क्लास

इस तरह यह करना:

object MyApplication: Application(){} 

काम नहीं करेगा। मिली त्रुटियाँ के बाद कार्यावधि में फेंक दिया जाता है:

java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation. 

ऐसा भी संभव नहीं है:

class MyApp: Application() { 

    private val instance_: MyApp 

    init{ 
     instance_ = this 
    } 

    override fun onCreate() { 
     super.onCreate() 
     if (BuildConfig.DEBUG) { 
      Timber.plant(Timber.DebugTree()); 
     } 
    } 

    companion object{ 
     fun getInstance() = instance_   
    } 
} 

तो मैं कैसे अपने आवेदन वर्ग मेरे एप्लिकेशन में हर जगह का एक उदाहरण हो सकता है, बजाय MyApp.instance() उपयोग करना चाहते हैं (applicationContext as MyApp) का।

यह भी एक स्पष्टीकरण है कि मैं यह क्यों चाहता हूं: मेरे पास मेरे ऐप में कक्षाएं हैं, उदाहरण के लिए, एक साझाप्रणाली सिंगलटन जिसे संदर्भ के साथ शुरू किया गया है, और इसके सिंगलटन के रूप में, तर्क नहीं हो सकते हैं।

उत्तर

15

यदि आप चाहते हैं तो कुछ स्थिर गुणों का उपयोग करने के लिए इसका उपयोग करें आपके पास है: आपके पास केवल आपके आवेदन का एक उदाहरण होगा, इसलिए बस कक्षा में दिए गए नाम का उपयोग करें। इस बारे में चिंता न करें कि यह वास्तविक सिंगलटन नहीं है, आप इसका उपयोग उसी तरह कर सकते हैं।

उदाहरण:

class MyApp : Application() { 

    companion object { 
     const val CONSTANT = 12 
     lateinit var typeface: Typeface 
    } 

    override fun onCreate() { 
     super.onCreate() 
     typeface = Typeface.createFromAsset(assets, "fonts/myFont.ttf") 
    } 

} 

तो फिर तुम MyApp.CONSTANT और MyApp.typeface आपके एप्लिकेशन में कहीं भी उपयोग कर सकते हैं।

-

क्या आप चाहते हैं एक आवेदन संदर्भ के रूप में उपयोग करने के लिए आप संदर्भ के लिए एक एक्सटेंशन संपत्ति बना सकते हैं यह है:

val Context.myApp: MyApp 
     get() = applicationContext as MyApp 

तो फिर तुम myApp उपयोग कर सकते हैं प्राप्त करने के लिए एप्लिकेशन संदर्भ कहीं भी आपके पास एक संदर्भ है।

+0

यह अच्छा @nitrico दिखता है, लेकिन मुझे'val Context.myApp नहीं मिल सकता है: MyApp () = एप्लिकेशन कॉन्टेक्स्ट को MyApp 'भाग के रूप में प्राप्त करने के लिए मिलता है। क्या आप थोड़ा और विस्तार में जा सकते हैं? जहां इस लाइन को जाने की जरूरत है और इसे किसी अन्य वर्ग में कैसे पहुंचाया जाए? – shredder

2

आप ऐसा नहीं कर सकते क्योंकि एंड्रॉइड अपने पैरामीटर रहित कन्स्ट्रक्टर का उपयोग करके Application इंस्टेंस बनाता है।

जिस समस्या को आप हल करना चाहते हैं उसे DI के साथ आसानी से हल किया जा सकता है। बस एक इंजेक्टर के साथ उदाहरण बनाएं ताकि Context को निर्भरता के रूप में वस्तुओं में इंजेक्शन दिया जा सके।

+0

या मैं हमेशा उस समाधान के बारे में जानता था लेकिन उम्मीद कर रहा था कि एक और तरीका था। धन्यवाद आदमी –

29

आप जावा में ऐसा ही कर सकते हैं जो आप जावा में करेंगे, यानी Application उदाहरण को स्थिर क्षेत्र में रखें। कोटलिन में स्थिर क्षेत्र नहीं हैं, लेकिन वस्तुओं में गुण स्थिर रूप से सुलभ हैं।

class MyApp: Application() { 

    override fun onCreate() { 
     super.onCreate() 
     instance = this 
    } 

    companion object { 
     lateinit var instance: MyApp 
      private set 
    } 
} 

फिर आप MyApp.instance के माध्यम से संपत्ति का उपयोग कर सकते हैं।

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