2011-07-06 6 views
8

Pracuję nad projektem, który ma aktywność na niższym poziomie o nazwie RecordView, aby wyświetlić szczegóły rekordu, takie jak obraz, datę i godzinę jego wykonania, a także informacje o szerokości i długości geograficznej. Zamiast próbować manipulować aparatem w celu geotagu i uzyskać dostęp do danych exif, próbuję zaimplementować odbiornik lokalizacji, aby uzyskać lokalizację, w której obraz jest po raz pierwszy zrobiony (w naciśnięciu przycisku). To podejście działa - otrzymuję moją lokalizację do poprawnego wyświetlenia i aktualizacji rekordu w bazie danych (powrót do widoku później wyświetla lokalizację od początku). Jeśli jednak wycofam się z obecnego RecordView, a następnie wprowadzę kolejne dwa (dowolna kombinacja), program ulegnie awarii z błędem InstanceCountViolation (pełny błąd zostanie przedrukowany poniżej). Kiedy nadpisuję metody życia do RecordView, aby wyświetlić, gdy każdy jest wywoływany, stwierdzamy, że jest on niszczony przed ponownym wywołaniem. To znaczy, nie wydaje się, że istnieje więcej niż jeden RecordView w danym czasie.Wielokrotne otwieranie podktywności powoduje naruszenie InstanceCount pomimo zniszczenia

Moje pytanie sprowadza się do tego: skąd pochodzi ten błąd i jak mogę to naprawić?

Czy coś kłamie na temat bycia zniszczonym? Czy LocationListener gdzieś siedzi i powoduje problemy? Czy to coś niezwiązanego, co może świadczyć o fałszywym błędzie?

Ponadto, czy powinienem zrobić straszliwą naprawę z twardym kodem i po prostu zwiększyć dozwoloną liczbę wystąpień RecordView? Lub kontynuuj polowanie na inne podejście (na przykład próbuję zażądać pojedynczej aktualizacji przy użyciu połączenia PendingIntent.getBroadcast(...))?

Dla odniesienia ten błąd pojawił się na emulatorze dla wersji 3.1 i na rzeczywistym tablecie (Xoom, 3.1). Komentowanie kodu aktualizacji odbiornika wydaje się unikać awarii (EDIT 2: Wygląda na to, że się mylę). Kod odnoszący się do odbiornika znajduje się poniżej (można go znaleźć w publicznej metodzie updateLocation wewnątrz klasy RecordView).

// Listener for the update request 
    LocationListener locListener = new LocationListener() { 
     // Store the currentRecord so the listener can update it after return 
     Record currentRecord = record; 
     GeoDatabase database = data; 
     @Override 
     public void onLocationChanged(Location location) { 
      if (location != null) { 
       myLocation = location; 
       Log.d(TAG, "Location pulled as " + myLocation); 
       String lat = Location.convert(myLocation.getLatitude(), 
         Location.FORMAT_SECONDS); 
       String lon = Location.convert(myLocation.getLongitude(), 
         Location.FORMAT_SECONDS); 

       // Update the record values 
       currentRecord.setRecordLatitude(lat); 
       currentRecord.setRecordLongitude(lon); 
       database.updateRecord(currentRecord); 
       Log.d(TAG, "Record values now listed as "+ record.getValues()); 

       // Update the text boxes 
       latitude.setText(lat); 
       longitude.setText(lon); 

       Toast.makeText(getBaseContext(),"GPS location updated", 
         Toast.LENGTH_LONG).show(); 
      } else { 
       Log.w(TAG, "Passed location is null!"); 
       Toast.makeText(getBaseContext(), 
         "GPS error - unusable location", 
         Toast.LENGTH_LONG).show(); 
      } 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      Toast.makeText(getBaseContext(), 
        "GPS disabled", Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      Toast.makeText(getBaseContext(), 
        "GPS enabled", Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
     } 
    }; 

    lm.requestSingleUpdate(LocationManager.GPS_PROVIDER, locListener, null); 

Pełne błąd:

android.os.StrictMode$InstanceCountViolation:class [program path].RecordView; instances=3; limit=2 
    at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1) 

EDIT:

dwie rzeczy mam ustalona.

Po pierwsze, gdy Logcat pokazuje zniszczenie aktywności RecordView, LocationListener jest poprawnie rozłączony (zniszczony? Jest i tak pusty). Jednak wydaje się, że słuchacz aktualizuje się z poziomu poza grobem - czasami widzę komunikat "Toast" o aktualizacji GPS na ekranie aktywności na wyższym poziomie, a informacja o GPS wydaje się być zaktualizowana.

Po drugie, nie jest to dokładnie błąd na jedno zdanie - wydaje się, że jest to siła zamykająca RecordView zamiast całej aplikacji. Główna część aplikacji wydaje się po prostu być zminimalizowana.

EDIT 2:

Niedawno dodane ekran preferencji stosując nową działalność i ma taki sam błąd jak InstanceCountViolationRecordView. Sprawdziliśmy, że nic nie musi zostać zmienione w działaniu, aby wystąpił błąd: należy go otworzyć tylko kilka razy.Przykładem jak otwieramy nasze sub-działań z głównych działań jest poniżej:

Intent intent = new Intent(this.getActivity() 
     .getApplicationContext(), RecordView.class); 
Bundle extras = new Bundle(); 
extras.putString("tableName", "table1"); 
extras.putInt("id", mId); 
extras.putBoolean("newRecord", false); 
extras.putLong("folder_id", mFolderId); 
extras.putString("type", recordList.get(mId).getTableName()); 
intent.putExtras(extras); 

startActivity(intent); 

Więc teraz zastanawiam się, czy jest to problem, w jaki sposób zamiarem jest stworzenie obsługi działalności i usunięcia.

+0

Hej, czy kiedykolwiek to rozgryzłeś? Po prostu wpadłem na to sam z działaniem preferencyjnym. –

+0

@AndyD Niestety nie. Kiedy wyłączyliśmy tryb ścisły, wydawało się, że działa poprawnie, ale oczywiście to nie jest prawdziwa naprawa ... – thegrinner

+0

Właśnie zadałem podobne pytanie przed znalezieniem tego: http://stackoverflow.com/questions/15368187/android -strict-mode-detects-multiple-activity-instance-violation-but-i-have-no – Jules

Odpowiedz

0

Wydaje się, że nie powinno być potrzebne, ale czy próbowałeś dzwoniąc

lm.removeUpdates(locListener);

aby wyrejestrować słuchacza?

0

Wiem, że to stary post. Tylko dla facetów, którzy szukają rozwiązania i wyjaśnienia tego problemu.

W przypadku wystąpienia wyjątku InstanceCountViolation oznacza to, że może występować rzeczywisty problem z wyciekiem aktywności lub problem związany z tym, w jaki sposób sprawdzana jest funkcja wykrywaniaAktywnośćLeaks w pakiecie Android SDK.

Aby określić, czy jest to problem, mogę polecić następujący wpis: Detecting leaked Activities in Android. Jeśli zauważysz, że istnieją obiekty odwołujące się do tego działania, które nie są powiązane z systemem Android, masz problem, który powinien zostać przez Ciebie rozwiązany.

W przypadku, gdy nie ma żadnych obiektów zawierających odniesienie do tego działania, które nie są powiązane z platformą Android, oznacza to, że napotkano problem związany z implementacją sprawdzania detekcjiAktywnośćLeaks. W tym przypadku, aby rozwiązać problem z uszkodzonym działalności bez wyłączania detectActivityLeaks można po prostu uruchomić System.gc() przed rozpoczęciem działalności w konfiguracji debugowania jak w poniższym przykładzie:

if (BuildConfig.DEBUG) 
{   
    System.gc(); 
} 

Intent intent = new Intent(context, SomeActivity.class); 
this.startActivity(intent); 

Więcej informacji dostępne są w tym answer.

Powiązane problemy