RecordView
画像、撮影日時、緯度/経度情報などのレコードの詳細を表示するために呼び出される下位レベルのアクティビティを持つプロジェクトに取り組んでいます。カメラを操作してジオタグを付け、exif データにアクセスしようとするのではなく、位置リスナーを実装して、画像が最初に撮影された場所 (ボタンを押したとき) を取得しようとしています。このアプローチは機能します-データベース内のレコードを正しく表示および更新するために自分の場所を取得します(後でビューに戻ると、場所が最初から表示されます)。ただし、現在の状態から戻って、RecordView
さらに 2 つ (任意の組み合わせ) を入力すると、プログラムはエラーでクラッシュしますInstanceCountViolation
(完全なエラーを以下に再掲します)。の生涯メソッドをオーバーライドするとRecordView
それぞれが呼び出されたときに表示するには、再度呼び出される前に破棄されていることがわかります。つまり、常に 1 つ以上RecordView
存在するようには見えません。
だから私の質問はこれに要約されます:そのエラーはどこから来て、どうすれば修正できますか?
破壊されたことについて何か嘘をついていますか?LocationListener がどこかに座っていて、問題を引き起こしていますか? 偽のエラーを提供している可能性があるのは無関係ですか?
また、ハードコードされた恐ろしい修正を行い、RecordView
許可されているインスタンスの上限を引き上げる必要がありますか? または、別のアプローチを探し続けますか (例として、PendingIntent.getBroadcast(...)
呼び出しを使用して単一の更新を要求しようとしています)?
参考までに、このエラーは 3.1 のエミュレーターと実際のタブレット (Xoom、3.1) で発生しています。リスナーの更新コードをコメントアウトすると、クラッシュを回避できるようです (編集 2 : 私はそれについて間違っていたようです)。リスナーに関連するコードを以下に示します (クラス内の public メソッドupdateLocation
内にあり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);
完全なエラー:
android.os.StrictMode$InstanceCountViolation:class [program path].RecordView; instances=3; limit=2
at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
編集:
決めたことは2つ。
1 つ目は、Logcat がアクティビティの破棄を示している場合、RecordView
アクティビティLocationListener
が正しく切断されていることです (破棄されていますか? とにかく null です)。ただし、リスナーは墓の向こうから更新されているようです。つまり、上位レベルのアクティビティ画面で GPS 更新に関するトースト メッセージが表示され、GPS 情報が更新されたように見えることがあります。
RecordView
2 つ目は、アプリ全体ではなく強制終了のように見えることです。アプリのメイン チャンクは、基本的に最小化されているようです。
編集2:
最近、新しいアクティビティを使用して設定画面を追加しましたが、これには と同じInstanceCountViolation
エラーがありRecordView
ます。エラーが発生するためにアクティビティで何も変更する必要がないことを確認しました。数回開くだけで済みます。メイン アクティビティからサブ アクティビティを開く方法の例を以下に示します。
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);
だから今、インテントがアクティビティの作成と削除を処理する方法に問題があるのではないかと思っています。