2009-05-21 4 views
22

showDialog()dismissDialog()을 사용하여 내 앱에서 진행 대화 상자를 표시합니다. 대화 상자를 생성하지 않고 오리엔테이션을 변경할 때 상태를 저장하기 위해 show()을 호출하는 것으로 이동했습니다.Android - dismissDialog가 대화 상자를 닫지 않습니다.

그러나 portrait-> landscape-> portrait에서 방향을 변경하면 dismissDialog()이 더 이상 대화 상자를 닫지 않습니다. 대화 상자는 항상 거기에 머물러 있으며 뒤로 버튼을 눌러야 사라집니다.

그런 식으로 행동하는 이유는 무엇입니까? 편집

내가 removeDialog() 그래서 대화 상자가 생성되지 않는다는/회와 방향이 변경되기 전에 표시 대화 상자가 제거 onDestroy()에 추가 시도,이 문제를 극복하기 위해. 시도 활동이 표시 될 때 처음에이 onCreateDialog 한 번와 방향 변경에 대한라고, 로그 문을 추가하고 우리가 여기에서 볼 경우

05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog 

05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState 
05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy 

05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState 
05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy 

05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window [email protected] that was originally added here 

05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog 
05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog 
05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog 

를 어떻게 볼, onSaveInstanceState 및들의 OnDestroy가 호출된다.

그러나 그 후에 onCreateDialog가 두 번 호출됩니다 (한 번 showDialog를 호출하면 두 번째 시간이 표시됩니까?). 그러면이 방향이 바뀔 때마다이 작업이 수행됩니다.

그 이유는 무엇입니까?

다시 한번 감사

+0

을 바탕으로? 이 문제에 관해 많은 게시물과 블로그를 보았지만 해결할 솔루션이없는 것 같습니다. – lostInTransit

답변

0

(DialogonCreateDialog 통해 결과적으로의)가 생성 될 때마다 당신이 당신의 Activity의 새로운 인스턴스를 방향을 변경 양해하여 주시기 바랍니다. 두 생성자 중 하나에서 로그 문을 추가하여이를 확인할 수 있습니다.

코드를 한 눈에 알지 못해도 말하기 어렵지만 Activity의 이전 인스턴스에서 dismissDialog을 호출하는 것 같습니다. 이 코드는 당신이 설명하고있는 것과 유사한 문제가

public class Test extends Activity { 

    private Dialog dialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.test); 
     Button btn = (Button) findViewById(R.id.testButton); 
     btn.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       new Timer().schedule(new TimerTask() { 
        @Override public void run() { dialog.dismiss(); } 
       }, 10000); 
       Test.this.showDialog(1); 
      } 
     }); 
    } 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     if(id == 1) { 
      if(dialog == null) { dialog = new Dialog(this); } 
      return dialog; 
     } 
     return super.onCreateDialog(id); 
    } 
} 

:

는 단순히 버튼을 클릭 빈 Dialog를 표시하고 10 초 후에이를 기각 할 TimerTask을 시작 Activity을 다음 고려 : 10 초 동안 방향이 바뀌면 Dialog은 절대로 없어지지 않습니다. 왜? 때문에 상기 TimerTaskrun (방향 변경 중에) 생성 된 TestDialog 인스턴스 완전히 다른 세트 인 시간 및 TimerTaskdialog 인스턴스 변수 참조에 현재 활성화 된 것과 다른 Test 인스턴스에서 화면.

private static Dialog dialog;
+0

Josef에게 감사드립니다. 하지만 그 수정이 실제로 해킹이라고 말한 것처럼! 나는 서비스를 대신 사용하려고 생각하고있다. 서비스가 실행될 때까지 대화 상자를 표시합니다. 이 문제를 해결하는 올바른 방법일까요? – lostInTransit

+0

정말 응용 프로그램에 따라 다릅니다. 그러나 당신 말이 맞습니다. (아주) 장기간 실행되는 작업은 반드시 서비스에 투입되어야합니다. –

4
:

는 물론 단순히 dialog 필드 static를 만들기 위해이 문제 (대부분의 응용 프로그램에 따라 다름), 하나의 빠른 (? 더러운)이 될 것입니다 위의 코드를 수정하는 방법을 처리하는 방법에는 여러 가지가 있습니다

나는 최근에이 문제도 만났다.전역 개체 (db 연결, 데이터 목록 등)에 액세스해야하는 많은 활동이있는 응용 프로그램이 있으므로 응용 프로그램 클래스를 오버로드합니다. 이를 위해 필자는 대화 상자를 닫으려고 사용하는 runnable의 진행 대화 상자의 최신 인스턴스에 대한 참조 만 필요하다는 사실을 깨달았습니다. 이것은 내가 무엇을 최대 온이며 우아하게 전화 reorientations 남아 :

private Runnable showProgressRunnable = new Runnable() { 
    public void run() { 
     mProgressDialog.show(); 
    } 
}; 

private Runnable hideProgressRunnable = new Runnable() { 
    public void run() { 
     if (mApplication.getProgressDialog() != null) { 
      mApplication.getProgressDialog().dismiss(); 
     } 
    } 
}; 

내 스레드가 mHandler.post (showProgressRunnable)를 수행 ....

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.preferences); 

    mHandler = new Handler(); 
    mApplication = (MyApplication)getApplication(); 

    mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage"); 

    mProgressDialog = new ProgressDialog(this); 

    mProgressDialog.setTitle("Location Update"); 
    mProgressDialog.setMessage("Moving databases to new storage location."); 
    mProgressDialog.setIndeterminate(true); 
    mProgressDialog.setCancelable(false); 
    mProgressDialog.setCanceledOnTouchOutside(false); 

    mApplication.setProgressDialog(mProgressDialog); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
    mPreferences.registerOnSharedPreferenceChangeListener(this); 

    if (sUpdateThread != null && sUpdateThread.isAlive()) { 
     mProgressDialog.show(); 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 

    mPreferences.unregisterOnSharedPreferenceChangeListener(this); 

    if (sUpdateThread != null && sUpdateThread.isAlive()) { 
     mProgressDialog.hide(); 
     mApplication.setProgressDialog(null); 
    } 
} 

.... 여기에 임의의 물건을 할 때 작업이 시작되면 mHandler.post (hideProgressRunnable)가 수행됩니다. 최신 ProgressDialog에 대한 참조가 Application 클래스에 저장되었으므로 더 이상 이전 객체 참조를 유지하지 않으므로 안정적으로 닫을 수 있습니다. 후세를위한

링크 : 내가 ShowDialog를 (MyDialogID)를 호출

과 handleMessage 중 dismissDialog (MyDialogId) (myMessage) : http://developer.android.com/reference/android/app/Application.html

0

포럼의 모든 종류를 검색 후, 난 그냥 다음을했다 내 처리기의 메서드입니다.

전에 내 onCreate() - 메서드에서 showDialog를 호출하고 handle-Message에서 대화 상자를 닫으려고했습니다. 왜 이것이 문제를 해결했는지 나는 알 수 없다.

6

작업의 onCreate 재정의 대화 상자를 표시 할 때이 문제가 발생했습니다. 대신 대화 상자가 onPostCreate 오버라이드에 표시되도록하는 코드를 이동해보십시오. 이것은 나를 위해 작동하는 것 같다.

+0

onCreate()에서 showDialog()와 동일한 문제가 발생했습니다. 비록 디버거를 통해 앱을 시작할 때만 발생하는 것으로 보입니다. onPostCreate()로 showDialog()를 이동하면 저에게 감사드립니다! - 감사합니다! – sstn

+0

위대한 솔루션, 단지 대화 상자를 시작하려면 OnPostCreate를 사용하십시오 ... @Override public void onPostCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); launch_app(); } –

+0

다음은 문서화 된 Android 버그입니다. http://code.google.com/p/android/issues/detail?id=24646 –

7

나에게 가장 좋은 해결책은 dismissDialog() 대신 removeDialog (id)를 사용하는 것 같습니다. 이 방법은 재사용이 적지 만 방향을 변경할 때 더 안전하고 (아무 것도 던지지 않음) 문제가 없습니다.

3

응용 프로그램으로 돌아 왔을 때 홈 버튼을 누르고 더 로컬로 이동 한 다음 (장치 언어 변경), dismissDialog를 통해 새 대화 상자를 닫을 수 없었습니다 (활동 onCreate에서 대화 상자를 시작했습니다).

해결책은 dissmissDialog() 대신 removeDialog를 호출하는 것이 었습니다. 위의 Harri가 추천 한 Thx입니다.

13858


솔루션 대신 한 OnCreate의 OnPostCreate 사용하여 대화 상자를 만드는 것입니다 :

나는 안드로이드 버그 보고서를 만들었습니다. 그 정보를 버그 보고서에 추가하고 dialog documentation을 개선 할 것을 권장했습니다.

5

dismissDialog를 호출 할 때 대화 상자가 닫히지 않으면 서 이와 같은 문제가 하루 이상 낭비되었습니다. 내 첫 번째 화면 회전 후 발생하고 이후에 작동하지 않습니다. 나는 명시 적으로 상태에 참조 된 전달 된 외부 AsyncTask를 사용하고 있었다.

결국 솔루션은 매우 간단했습니다 .... removeDialog(int)dismissDialog(int) 대신.

나 자신에게 증명할 수있는 것처럼 보였던 것을 보냈다. 나는 정확한 활동에 대해 해고하고 일이 불려지는 횟수를 확인했지만, 장면 뒤에있는 일종의 짐승 냄비 때문에 발생했다.

0

동일한 문제를 실험하고있었습니다. onCreateDialog() 콜백 내에 AlertDialogProgressDialog을 생성하여 onCreate()에서 표시했습니다. onCreate (onCreateDialog()을 사용하지 않고)에서이 대화 상자를 직접 생성하고이를 onPause()에서 삭제하면 나를 위해 일했습니다! 누군가가이 문제를 좀 도와 주시겠습니까 https://stackoverflow.com/a/5693467/955619

0
private AlertDialog alert11 = null; 
public void gpsDialog(){ 
    if (alert11 == null || !alert11.isShowing()) { 
     AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this); 
     builder1.setMessage("GPS not On"); 
     builder1.setCancelable(true); 

     builder1.setPositiveButton("Enable GPS", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 

        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        MainActivity.this.startActivity(intent); 
        dialog.dismiss(); 
       } 
      }); 

     builder1.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        dialog.dismiss(); 
       } 
      }); 

    alert11 = builder1.create(); 

    alert11.show(); 

    } 

} 
관련 문제