Singltons vs Android tətbiqi kontekstində?

Bu məqalədə təklinlərdən istifadə etmək və bir neçə nümunə nümunələrini bir tək nümunə modelindən istifadə edərək xatırladaraq, tətbiqin qlobal dövləti ilə paylaşdıqları tək nümunələrdən fərqli olaraq, singletons istifadə etməyinizə məcbur edirsiniz (subclassing android.os.Application və kontekstdən əldə etmək. getApplication ()).

Hər iki mexanizmin üstünlükləri / dezavantajları hansılardır?

Dürüstcə, bu mesajda eyni cavabı gözləyirəm İnternet tətbiqi ilə Singleton şablonu yaxşı bir fikir deyil! ancaq Android tətbiq olundu. Am i sağ Digər şəkildə DalvikVM fərqli nədir?

EDIT: Mən bir neçə cəhətdən fikirlərini almaq istərdim:

  • Sinxronlaşdırma
  • Yenidən istifadə edin
  • Test
313
30 сент. set mschonaker 30 sept. 2010-09-30 03:35 '10 at 3:35 2010-09-30 03:35
@ 10 cavab

Dianna Hackborn'ın cavabı ilə həqiqətən razılaşmıram. Projemizden yavaş yavaş yavaş yavaş, həqiqətən ehtiyac duyduğunuzda asanlıqla bərpa edilebilecek belirli alanlara sahip hafif objelerin lehine kalırız.

Singletons test üçün bir kabusdur və əgər bu tənəffüslə başlayırsa, incin yan təsirləri ilə "dövlət qeyri-müəyyənliyini" (birdən-birə getinstance () bir sahədən digərinə hərəkət edərkən birdən-birə görünə bilər) təqdim edəcəkdir. Görünürlük başqa bir problem olaraq adlandırılıb və bir nöqtədə ümumi vəziyyətə "qlobal" (= təsadüfi) daxil olmaq üçün paralel tətbiqlərdə sinxronlaşdırılmırsa, incə səhvlər yarana bilər.

Mən bu bir anti-nümunə hesab edirəm, bu qlobal bir dövlətin qorunması üçün əhəmiyyətli dərəcədə aşağı düşən yoxsul obyekt yönümlü bir tərzdir.

Sualınıza qayıtmaq üçün: Proqram kontekstinin təkli olaraq baxılmasına baxmayaraq, infrastruktur tərəfindən idarə olunur və yaxşı müəyyən edilmiş bir həyat dövrü, əhatə dairəsi və giriş yolu var. Buna görə də inanıram ki, qlobal-qlobal dövləti idarə etməliyəmsə, bura başqa bir yerə getməli. Başqa bir şey üçün, həqiqətən, bir təkli obyektə ehtiyacınız varsa yenidən düşünün və ya əvəzinə əvəzinə yerinə yetirən vəzifəni yerinə yetirən kiçik, qısamüddətli obyektlər yaratmaq üçün təklink sinifinizi yenidən yaza bilərsiniz.

279
08 окт. Matthias tərəfindən verilmiş cavab 08 oktyabr 2010-10-08 10:39 '10 at 10:39 2010-10-08 10:39

Tək təklif edirəm. Kontekstə ehtiyac duyan bir təklisiniz varsa, bu addımları edin:

 MySingleton.getInstance(Context c) { // // ... needing to create ... sInstance = new MySingleton(c.getApplicationContext()); } 

Tətbiqə görə birincilərə üstünlük verirəm, çünki daha çox mütəşəkkil və modul tətbiqi saxlamağa kömək edir - bütün qlobal dövlətin ərizədə saxlanılması lazım olan bir yerə malik olmağın əvəzinə hər bir fərdi hissə özü ilə maraqlana bilər. Ayrıca, Singltons'un tətbiqi ilə başlamasının yerinə yetirmək əvəzinə, başqalarına lazily olaraq (istek üzerine) başlamasının olması yaxşıdır.

border=0

Singletons istifadə həqiqətən bir şey yoxdur. Mantiqli olduğunda onları düzgün istifadə edin. Əslində, Android verilənlər bazasında çoxları var, çünki onlar hər bir prosesdə yüklənə bilən resursların və digər oxşar əşyaların önbelleğinin dəstəklənməsini dəstəkləyirlər.

Bununla yanaşı, sadə tətbiqlər üçün multithreading təkli problemlər olmayacaq, çünki dizaynla bütün standart geri çağırışlar əsas proses axını boyunca göndərilir, belə ki, işəgötürənlər tərəfindən aydın şəkildə təqdim etməyiniz və ya kontent provayderinin və ya digər proseslərə IBinder xidmətləri təqdim edir.

Nə etdiyinizi düşünün. :)

211
30 сент. Hackbod tərəfindən verilmiş cavab Sep 30 2010-09-30 04:48 '10 at 4:48 2010-09-30 04:48

Gönderen: http://developer.android.com/reference/android/app/Application.html

Bir qayda olaraq ərizə alt sinifinə ehtiyac yoxdur. Çox hallarda, statik təkanlar eyni funksiyanı daha modul bir şəkildə təmin edə bilər. Sizin singletonunuz bir qlobal kontekstə ehtiyac duyarsa (məsələn, yayım alıcılarını qeydiyyatdan keçirmək üçün) ilk funksiyanı yaratdığımız zaman Context.getApplicationContext () funksiyasını istifadə edən bir kontekst verilə bilər.

17
23 марта '12 в 20:26 2012-03-23 20:26 Cavab Somatik tərəfindən 23 Mart 2012 tarixində saat 20: 26-da verilir. 2012-03-23 ​​20:26

Eyni problemim vardı: singleton və ya android.os.Application bir alt sinif?

Əvvəlcə Singleton istifadə etməyə çalışdım, amma bir anda mənim müraciətim brauzerə zəng edir

 Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); 

problemi telefonun kifayət qədər yaddaşa malik olmadığını göstərirsə, siniflərinizin bir çoxu (hətta Singletons) brauzerdən mənim ərizəimə qayıdarkən bir qədər yaddaş yığılır, hər dəfə pozulur.

Həll: zəruri məlumatları tətbiq sinfi alt sinifinə qoyun.

11
05 окт. JoséMi tərəfindən verilmiş cavabı Oct 05. 2010-10-05 20:11 '10 'da 20:11' də, 2010-10-05 20:11

Bu proqramlar singleletondan fərqlidir. Nedenler:

  • Tətbiq metodu (məsələn, onCreate) ui axında çağırılır;
  • singleton metodu hər hansı bir mövzuya çağırıla bilər;
  • Ərizənin "onCreate" üsulunda Handler bir nümunəsi yarada bilərsiniz;
  • Birbaşa əlaqəli bir işdə icra edildiyində, işəgötürənə nümunə ola bilməz;
  • Ərizədə tətbiqdə fəaliyyətlərin həyat dövrü idarə etmək imkanı var. "RegisterActivityLifecycleCallbacks" metodu var. Ancaq təkliklərdə heç bir qabiliyyət yoxdur.
10
26 марта '14 в 11:53 2014-03-26 11:53 cavab 26 mart '14 'də saat 11:53' də verilir. 2014-03-26 11:53

Hər ikisini eyni anda nəzərdən keçirin:

  • sinif daxilində statik nümunələr kimi təkli obyektlərlə.
  • tətbiqi içində bütün singelton obyektləri üçün tək nümunələri döndərən ümumi bir sinif (Kontekst) ilə əlaqəli metod adları istifadə edə bilərsiniz: context.getLoggedinUser () yerine User.getInstance ().

Bundan əlavə, konteksti yalnız tekli obyektlərə daxil olmaq üçün deyil, həmçinin, dünyada, məsələn, bir neçə funksiyaya daxil olmaq üçün təklif edir: context.logOffUser (), context.readSavedData () və t .d Yəqin ki, adın dəyişdirilməsi fasadın kontekstində mənalı idi.

5
08 окт. cavab 08 yanvar adranale verildi . 2010-10-08 15:01 '10 at 15:01 2010-10-08 15:01

Onlar əslində eynidırlar. Gördüyüm bir fərq var. Tətbiq sinfi istifadə edərək, dəyişənlərinizi Application.onCreate () proqramına başlamaq və onları Application.onTerminate () proqramında məhv edə bilərsiniz. Singleton istifadə edərkən, VM başlatma və statik məhv etməliyik.

4
30 сент. Cavab Fedor Sep 30 2010-09-30 04:13 '10 at 4:13 2010-09-30 04:13

Mənim 2 qəpik:

Mənim fəaliyyətim məhv edildiyi zaman tək / statik sahələrin bəzilərinin sıfırlandığını hiss etdim. Bunu aşağı 2.3 olan bəzi qurğularda gördüm.

Mənim işim çox sadə idi: mən yalnız özəl init_done və activity.onCreate () dan çağırdığım statik bir init üsulu var. Hesab edirəm ki, init üsulu yenidən fəaliyyətinin bərpası ilə yenidən başlamışdır.

Mənim bəyanımı təsdiq edə bilməməmə baxmayaraq, bu təklinlə / sinif ilk dəfə yaradıldığında / istifadə olunduğuna görə ola bilər. Bir hərəkət məhv edildikdə / təkrar istifadə edildikdə, yalnız bu hərəkətə aid olan bütün sinif, həm də təkrar istifadə edilir.

Mənim singleton nümunəsini, Application sinifinin alt sinifinə köçürdüm. Onlara ərizə formasından qoşuluram. və o vaxtdan bəri problemi bir daha görməmişdilər.

İnşallah kimsə bu kömək edə bilər.

3
23 июня '14 в 11:06 2014-06-23 11:06 Cavab Məsih tərəfindən 23 İyun, '14 'da 11:06 2014-06-23 11:06 tərəfindən verilir

Mənim fəaliyyətim bitiş () (dərhal başa çatdırmır, amma nəticə vermir) səbəb olur və Google Street Viewer-ı çağırır. Mən Eclipse-də disk bölüşdürdüyümdə, proqramı bağlamaq Street Viewer çağırıldığı zaman kəsilir, ancaq tamamilə yaddaşda olan bir proqram kimi başa düşürəm (hərəkətin bir fasiləsi bu davranışa səbəb olmamalıdır) Dövləti paketin üzərinə onSaveInstanceState () vasitəsilə qorumaq və yığındakı növbəti hərəkətin onCreate () metodunda bərpa edə bilərəm. Statik tək və ya subclassical tətbiqi istifadə edərək, proqramı bağlayaraq və itirməklə üzləşirəm (əgər paketdə saxlamıramsa). Buna görə də, mənim təcrübəmdə onlar dövlətin qorunması ilə bağlıdırlar. Bağlılıq Android 4.1.2 və 4.2.2-də itirildiyini, 4.0.7 və ya 3.2.4-də deyil, mənim fikrimcə yaddaş bərpa mexanizmi bir nöqtədə dəyişdiyini göstərir.

2
23 апр. 23 Apreldə Piovezan tərəfindən verilmiş cavab 2013-04-23 23:17 '13 at 11:17 pm 2013-04-23 23:17

Atın ağrılı ağızından ...

Bir tətbiq inkişaf etdirdiyiniz zaman, dünyanın, məlumatların, kontekstin və ya xidmətlərin paylaşılmasına ehtiyacınız ola bilər. Məsələn, ərizəinizdə hazırda daxil olan istifadəçi kimi seans verisi varsa, bu məlumatı təqdim etmək istəyirsən. Android-də bu problemin həlli yourroid.app.Application örneğinin bütün qlobal məlumatlara malik olması və müxtəlif məlumat və xidmətlər üçün statik aksessuarlar ilə tətbiqi sənət nümunəsini təkli olaraq işlədilməsidir.

Bir Android tətbiqi yazarkən, yalnız android.app.Application sinifinin bir nümunəsi var və buna görə də tək bir müalicə üçün təhlükəsiz (və Google Android qrupu tərəfindən tövsiyə olunur). Yəni, tətbiqi tətbiqinizə statik getInstance () üsulunu təhlükəsiz əlavə edə bilərsiniz. Beləliklə ...

 public class AndroidApplication extends Application{ private static AndroidApplication sInstance; public static AndroidApplication getInstance(){ return sInstance; } @Override public static void onCreate(){ super.onCreate() sInstance = this; } } 
0
26 июля '16 в 13:18 2016-07-26 13:18 Cavab RMcGuigan 26 iyul '13 saat 13:18 'də verilir 2016-07-26 13:18

əlaqədar digər suallar və ya bir sual