[android] Android : ProgressDialog.show ()가 getApplicationContext와 충돌합니다.

왜 이런 일이 일어나는지 이해할 수없는 것 같습니다. 이 코드 :

mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);

잘 작동합니다. 그러나이 코드 :

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

다음 예외가 발생합니다.

W/WindowManager(  569): Attempted to add window with non-application token WindowToken{438bee58 token=null}.  Aborting.
D/AndroidRuntime( 2049): Shutting down VM
W/dalvikvm( 2049): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime( 2049): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 2049): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tastekid.TasteKid/com.tastekid.TasteKid.YouTube}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.access$2100(ActivityThread.java:116)
E/AndroidRuntime( 2049):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
E/AndroidRuntime( 2049):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2049):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.main(ActivityThread.java:4203)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
E/AndroidRuntime( 2049):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 2049): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.view.ViewRoot.setView(ViewRoot.java:460)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 2049):    at android.app.Dialog.show(Dialog.java:238)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:107)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:90)
E/AndroidRuntime( 2049):    at com.tastekid.TasteKid.YouTube.onCreate(YouTube.java:45)
E/AndroidRuntime( 2049):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
E/AndroidRuntime( 2049):    ... 11 more

왜 이런 일이 발생하는지 아이디어가 있습니까? 나는 이것을 onCreate메소드 에서 호출하고 있습니다 .



답변

어떤 API 버전을 사용하고 있습니까? 문제가 옳다면 Android 1.6 (API 버전 4)에서 수정되었습니다.

getApplicationContext()null을 가리키는 객체 참조처럼 보입니다 . onCreate()윈도우가 실제로 빌드되기 전에의 일부 코드 가 실행되고 있다는 점에서 내가 가진 것과 비슷한 문제가 있다고 생각합니다 . 이것은 해킹이 될 것이지만 몇 백 밀리 초 안에 새 스레드를 시작해보십시오 (IIRC : 300-400이 저에게 적합한 것처럼 보였지만 수정해야 함) ProgressDialog를 열고 필요한 모든 것을 시작합니다 ( 예 : 네트워크 IO). 이 같은:

@Override
public void onCreate(Bundle savedInstanceState) {
    // do all your other stuff here

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mProgressDialog = ProgressDialog.show(
               YouTube.this.getApplicationContext(), "",
               YouTube.this.getString(R.string.loading), true);

            // start time consuming background process here
        }
    }, 1000); // starting it in 1 second
}


답변

API 레벨 7과 함께 Android 버전 2.1을 사용하고 있습니다.이 (또는 유사한) 문제에 직면하여 다음을 사용하여 해결했습니다.

Dialog dialog = new Dialog(this);

대신 :

Dialog dialog = new Dialog(getApplicationContext());

도움이 되었기를 바랍니다 🙂


답변

나를 위해 일하는 변화

builder = new AlertDialog.Builder(getApplicationContext());

builder = new AlertDialog.Builder(ThisActivityClassName.this);

이상한 점은 첫 번째는 Google 튜토리얼에서 찾을 수 있고 사람들은 이것에 대해 오류가 발생한다는 것입니다.


답변

이것이 null 응용 프로그램 컨텍스트와 관련된 타이밍 문제라고 생각하지 않습니다.

앱 내에서 애플리케이션을 확장 해보십시오 (또는 이미있는 경우 사용하십시오).

public class MyApp extends Application

인스턴스를 비공개 싱글 톤으로 사용할 수 있도록합니다. 이것은 null아닙니다.

private static MyApp appInstance;

MyApp에서 정적 도우미 만들기 (싱글 톤 사용)

    public static void showProgressDialog( CharSequence title, CharSequence message )
{
    prog = ProgressDialog.show(appInstance, title, message, true); // Never Do This!
}

팔!!

또한 여기에서 Android 엔지니어의 답변을 확인하십시오 : WindowManager $ BadTokenException

이 오류의 한 가지 원인은 활동이 아닌 컨텍스트를 통해 응용 프로그램 창 / 대화 상자를 표시하려고 할 수 있습니다.

자, 동의합니다. 메서드가 Activity 대신 Context 매개 변수를 사용한다는 것은 의미가 없습니다.


답변

위의 답변을 읽은 후 내 상황에 따라 다음 문제가 해결되었음을 알았습니다.

이로 인해 오류가 발생했습니다.

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(getApplicationContext());
        dialog.show();
    }
});

컨텍스트가 잘못되었음을 제안한 이전 답변을 기반으로 버튼 onClick 메서드에 전달 된 View에서 컨텍스트를 검색하도록 getApplicationContext ()를 변경했습니다.

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(v.getContext());
        dialog.show();
    }
});

나는 자바의 작동을 완전히 이해하지 못해서 내가 틀릴 수 있지만, 내 특정 상황에서 원인은 위의 스 니펫이 추상 활동 클래스에 정의되었다는 사실과 관련이있을 수 있다고 생각합니다. 많은 활동에서 상속되고 사용됩니다. 아마도 getApplicationContext ()가 유효한 컨텍스트를 반환하지 않는다는 사실에 기여했을 수 있습니까 ?? (그냥 추측).


답변

항목 별 오버레이가있는지도보기를 만들고 있습니다. 내 mapActivity에서 다음과 같이 itemizedoverlay를 만들었습니다.

OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);

내 itemizedoverlay의 onTap 메서드가 트리거 될 때 (위치가 mapview에서 탭될 때) “android.view.WindowManager $ BadTokenException : Unable to add window-token null is not for an application”예외가 발생한다는 것을 발견했습니다.

생성자에 ‘getApplicationContext ()’대신 ‘this’를 전달하면 문제가 해결된다는 것을 알았습니다. 이것은 alienjazzcat의 결론을 뒷받침하는 것 같습니다. 기묘한.


답변

TabActivities에 표시된 활동의 경우 getParent ()를 사용하십시오.

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

대신에

final AlertDialog.Builder builder = new AlertDialog.Builder(this);