2010-10-21 17 views
7

Tümü,Android NDK: Etkinliği yeniden başlattıktan sonra yerel kod nasıl temizlenir?

Varsayılan olarak, ekran yönlendirmesi değiştiğinde veya klavye kaydırıldığında veya çıkarıldığında bir etkinliğin öldürüleceğini ve yeniden başlatılacağını biliyorum. (Bkz. Activity restart on rotation Android). Sorum şu: Yerel kod perspektifinden bunu işlemenin doğru yolu nedir? Örneğin. Yerel bir kütüphaneyi yükleyen statik bir bloğum varsa ve uygulamam yeniden başlatılıyorsa, yerel arazideki herhangi bir belleğin uygun şekilde ele alınmasını nasıl sağlayabilirim? Eğer cihazı döndürdüğünüzde sorun

, bu ayrı bir Konu havuz oluşturulur ve eskileri kaldırıldı asla gibi görünüyor. Bu, her zaman birileri cihazı döner anlamına gelir, biz bir ton daha konu boşta oturan ve

Bunu nasıl olmamasını sağlamak do belleğini tüketebilir var? Dibinde JNIExample page bazı notlarından bkz:

[*] örnek ben mümkün değildi ki, kalan birkaç çözülmemiş sorunları vardır, tamamen işlevsel olmasına olsa Çözülmemiş sorunlar ve hatalar Şimdiye kadar anlamaya. etkinliğini başlattığınızda sorunlar görüntülenir, ardından gizlemek için Geri düğmesine basın ve sonra yeniden başlatın. Deneyimlerimden, yeniden başlatılan etkinlikte işlevlerine yapılan çağrılar, olağanüstü şekilde başarısız olacaktır. callVoid() basitçe, bir segmentasyon arıza ile çöküyor getNewData yapılan çağrılar() ve getDataString() neden JVM artık küresel önbelleğe nesne atfen mutlu çünkü bir hata ile iptal etmek iken. Etkinlik ( JVM kendisi yeniden anlamına gelmez aktivite yeniden başlatma) orijinal JVM içinde çalıştığını aktivite yeniden başlatma şekilde onlar NewGlobalRef() ile korunur halde bizim önbelleğe nesne başvurularını geçersiz görünür ve . Bunun neden olduğunu iyi bir açıklama yok, bu yüzden herhangi bir fikriniz varsa, lütfen bana bildirin.

Bu sorun çözüldü mü?

cevap

6

Android'de yeniden başlatma NDK rahatsız edici. Çevrenizdeki herhangi bir statik veri, işlemi yeniden kullandığından, yeni bir işlemde geçersiz olan her şeyi (herhangi bir OpenGL dokusu veya köşe nesnesi gibi) manuel olarak sıfırlamanız gerekir.Size yeni bir Java iş parçacığı ve yeni Java Uygulaması ve diğer nesneler de sunar, böylece uygulamanızın yeni bir örneğinde yeni olan nesnelerin önbelleğe alınmış tüm referansları da silinmelidir.

yüzden kullanmak strateji ikilidir: yeniden başlatılır Minimize ve yeniden başlatma herşeyi nuke. Eğer bağlantılı bir soruya yanıt olarak söylediği gibi

Sen in-app configChanges ele alarak yeniden başlatılır aza indirir. Ardından bir klavye açmak veya döndürmek, uygulamanın yeniden başlatılmasına neden olmaz; bu, herhangi bir uygulama için önemsiz olmayan başlangıç ​​süreleriyle olması gerektiği gibi. Benim uygulamanın yeni örneği başladığını algıladığında

Ve ben NewGlobalRef yoluyla üzerine düzenlenen herhangi bir Java nesneleri bırakmadan dahil olmak üzere bu noktada eski örneğinden kritik herşeyi bırakın. Statik verileri en aza indirgemeye çalıştım, ancak durağan nesneler etrafında tuttuğum kaçınılmaz yerlerden biri, yeni örneği algıladığımda onları temizliyorum.

eski ipler onlara hayır daha üstün referanslar vardır bir kez uzağa gitmeli (yani size NewGlobalRef tüm nesneleri yayımlanan bir kez).

2

VM yeniden başlatıldıysa, sıfırdan başlıyorsunuz. Değilse, devletin onu terk ettiğiniz yerdedir. NewGlobalRef'in altındaki şeyleri ortaya çıkaran önbelleğe alınmış nesne referanslarının geçersiz kılınması söz konusu değildir. Ben on the NDK mailing list wooyd makale hakkında birkaç not yazdım.

Etkinliğiniz yeniden başlatıldığında başlatılması gereken verilere sahipseniz, etkinliğinize açık bir başlatma çağrısı eklemeniz gerekir (onCreate'da, sanırım). Bir önceki turda sakladığınız herhangi bir şeyi doğru bir şekilde attığınızdan emin olun - DeleteLocalRef sonra NULL depolayın, sadece memset() sıfır.