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 InstanceCountViolation
RecordView
. 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.
Hej, czy kiedykolwiek to rozgryzłeś? Po prostu wpadłem na to sam z działaniem preferencyjnym. –
@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
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