2011-07-06 3 views
8

낮은 수준의 활동 인 RecordView이있는 프로젝트에서 작업하여 이미지, 촬영 날짜 및 시간과 같은 기록 세부 정보를 표시합니다. 위도/경도 정보. 위치 정보 태그를 지정하고 exif 데이터에 액세스하기 위해 카메라를 조작하는 대신 위치 청취자를 구현하여 이미지가 처음 촬영되는 위치를 얻으려고합니다 (버튼 누름). 이 접근 방식은 작동합니다 - 내 위치를 표시하고 데이터베이스의 레코드를 올바르게 업데이트합니다 (보기로 돌아가면 처음부터 위치가 표시됨). 그러나 현재 RecordView에서 철회 한 다음 두 개 (임의의 조합)을 입력하면 프로그램이 오류 InstanceCountViolation (아래에 전체 오류가 다시 인쇄 됨)과 충돌합니다. 각각의 호출시 표시 할 RecordView의 수명 메소드를 오버라이드하면 다시 호출되기 전에 파괴된다는 것을 알게됩니다. 즉, 주어진 시간에 하나 이상의 RecordView이 존재하는 것으로 나타나지 않습니다.하위 활동을 여러 번 열면 인스턴스가 손상 되었음에도 불구하고 InstanceCountViolation이 발생합니다.

제 질문은 다음과 같습니다. 오류가 어디에서오고 어떻게 해결할 수 있습니까?

파괴되는 것에 대해 뭔가가 있습니까? LocationListener가 어딘가에 앉아 있고 문제를 일으키고 있습니까? 가짜 오류를 제공하는 무언가가 관련이 있습니까?

또한 끔찍한 하드 코드 수정을하고 RecordView 인스턴스의 한도를 허용해야합니까? 또는 다른 방법을 찾기 위해 계속해서 수렵을 계속하십시오 (예 : PendingIntent.getBroadcast(...) 호출을 사용하여 단일 업데이트를 요청하려는 경우)?

이 오류는 3.1 용 에뮬레이터 및 실제 태블릿 (Xoom, 3.1)에 나타났습니다. 청취자 업데이트 코드를 주석으로 처리하면 충돌을 피할 수 있습니다 (EDIT 2 : 나는 그것에 대해 잘못 생각한 것 같습니다). 청취자와 관련된 코드는 아래에 있습니다 (RecordView 클래스의 public 메서드 updateLocation에서 찾을 수 있습니다).

// 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) 

편집 : 나는 결정했습니다

두 가지.

첫 번째는 Logcat에서 RecordView 활동이 삭제 된 것을 나타내면 LocationListener이 올바르게 연결이 끊어졌습니다 (파기 되었습니까? 어쨌든 null 임). 그러나 청취자는 그대로 무덤을 넘어서 업데이트하는 것처럼 보입니다. 즉, 상위 레벨 활동 화면에서 GPS 업데이트에 대한 토스트 메시지가 표시되고 GPS 정보가 업데이트 된 것 같습니다.

둘째, 말에 따라 정확히 충돌하지 않는다는 것입니다. 전체 앱이 아닌 RecordView이 강제 종료 된 것 같습니다. 응용 프로그램의 주요 덩어리는 기본적으로 최소화 된 것 같습니다.

편집 2 :

우리는 최근에 새로운 활동을 사용하여 기본 설정 화면을 추가하고 이것은 RecordView 같은 InstanceCountViolation 오류가 있습니다. 우리는 오류가 발생하는 활동을 바꿀 필요가 없음을 확인했습니다. 단지 몇 번 열어야 만합니다.우리는 주요 활동에서 우리의 방법론 작업 단위를 열 방법의 예는 다음과 같습니다

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); 

이제 텐트 활동 생성 및 삭제를 처리하는 방법에 문제가 있는지 궁금 해요.

+0

안녕하세요, 혹시 이것을 알아 냈습니까? 나는 환경 설정 활동으로 직접 실행했다. –

+0

@AndyD 불행히도. 엄격 모드를 해제했을 때 제대로 작동하는 것처럼 보였지만 분명히 실제 수정이 아니 었습니다 ... – thegrinner

+0

방금 ​​전에이 질문을 찾았습니다. http://stackoverflow.com/questions/15368187/android -strict-mode-detected-multiple-activity-instance-violation-but-i-have-no – Jules

답변

0

이 필요해서는 안 것 같다,하지만 당신은에

lm.removeUpdates(locListener);

리스너의 등록을 취소 호출 시도?

0

나는 이것이 오래된 게시물이라는 것을 알고있다. 이 문제에 대한 해결책과 설명을 찾고있는 사람들에게만 해당됩니다.

InstanceCountViolation 예외가있는 경우 Android SDK에서 detectActivityLeaks 검사가 구현되는 방식과 관련된 활동 누출 또는 문제가 있음을 의미합니다.

이것이 문제인지 확인하려면 다음 게시물을 권장 할 수 있습니다. Detecting leaked Activities in Android. Android 프레임 워크와 관련이없는이 액티비티에 대한 참조를 보유하고있는 객체가있는 것을 확인하면 문제가 해결됩니다.

이 액티비티에 대한 참조가있는 객체가 Android 프레임 워크와 관련이 없다는 것보다 detectActivityLeaks 검사가 구현 된 방법과 관련된 문제로 발생했음을 의미합니다. 이 사용할 수 있습니다

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

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

더 많은 정보 :이 경우는 단순히 다음 예에서와 같이 디버그 구성에 활동을 시작하기 전에 으로 System.gc()를 실행할 수 있습니다 detectActivityLeaks을 끄지 않고 실패 활동과 문제를 해결하기 위해 answer.