android - progressdialog範例 - progressdialog替代




Android:ProgressDialog.show()與getApplicationContext崩潰 (12)

(供將來參考)

我認為這是因為應用程序上下文和活動上下文存在差異,如下所述: http://www.doubleencore.com/2013/06/context/ : http://www.doubleencore.com/2013/06/context/

這意味著我們無法使用應用程序上下文顯示對話框。 而已。

我似乎無法理解為什麼會發生這種情況。 此代碼:

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方法調用這個。



在閱讀上述答案後,我發現對於我的情況,下面解決了這個問題。

這拋出了錯誤

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

根據之前提出的上下文是錯誤的答案,我更改了getApplicationContext()以從傳遞到按鈕onClick方法的View中檢索上下文。

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

我不完全理解Java的工作原理,所以我可能會錯誤,但我猜測對於我的具體情況,原因可能與以下事實有關:上面的代碼片段在Abstract Activity類中定義; 繼承和許多活動使用,也許這是由於getApplicationContext()不返回有效的上下文的事實? (只是猜測)。


如果您在groupActivity上遇到問題,請不要使用此功能。 PARENT是來自Parent ActivityGroup的靜態。

final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);

代替

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

對我而言,工作正在改變

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

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

奇怪的是,第一個可以在谷歌教程中找到和人們在這個上得到錯誤..


對於Android 2.2
使用此代碼:

//activity is an instance of a class which extends android.app.Activity
Dialog dialog = new Dialog(activity);

代替這個代碼:

// this code produces an ERROR:
//android.view.WindowManager$BadTokenException: 
//Unable to add window -- token null is not for an application
Context mContext = activity.getApplicationContext();
Dialog dialog = new Dialog(mContext);

備註:我的自定義對話框是在activity.onCreateDialog(int dialogId)方法之外創建的。


您使用的是哪個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
}

我不認為這是圍繞空應用程序上下文的時間問題

嘗試在你的應用程序中擴展應用程序(或者如果你已經有了,就使用它)

public class MyApp extends Application

將實例作為私有單例提供。 這從來不是空的

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

導致此錯誤的原因可能是嘗試通過不是活動的上下文來顯示應用程序窗口/對話框。

現在,我同意,該方法採用上下文參數而不是活動是沒有意義的。


我已經實現了警報對話框來處理當前活動視圖的異常。每當我給出這樣的結果時

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

給定相同的窗口異常。我編寫警告的onCreate()的代碼。很簡單,我用context = this;onCreate()方法中的setContentView()語句之後。將上下文變量視為全局Context context;

代碼示例是

static Context context;

 public void onCreate(Bundle savedInstanceState)  { 
        super.onCreate(savedInstanceState); 


        setContentView(R.layout.network); 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        context = this;
.......

警報方法示例是

private void alertException(String execMsg){
        Log.i(TAG,"in alertException()..."+context);
        Log.e(TAG,"Exception :"+execMsg);
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
.......

它適用於我。事實上,我在上搜索了這個錯誤,我發現這個查詢。閱讀了這篇文章的所有回復後,我嘗試了這種方式,所以它工作。我認為這是一個簡單的解決方案來克服這個異常。

謝謝,Rajendar


我正在使用API​​ Level 7的Android 2.1版。我遇到了這個(或類似的)問題,並通過使用這個問題來解決:

Dialog dialog = new Dialog(this);

代替這個:

Dialog dialog = new Dialog(getApplicationContext());

希望這可以幫助 :)


有(兼容性)Fragments類似的問題,在ProgressDialog.show()使用getActivity()使其崩潰。 我同意這是因為時機。

可能的解決方法:

mContext = getApplicationContext();

if (mContext != null) {
    mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}

而不是使用

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

盡可能早地放置mContext,以便有更多時間來獲取上下文。 這仍然不能保證,這只會減少崩潰的可能性。 如果它仍然不起作用,你將不得不採取計時器破解(這可能會導致其他計時問題,如稍後解除對話)。

當然,如果你可以使用thisActivityName.this ,它更穩定,因為this已經指向了某些東西。 但在某些情況下,如某些片段架構,這不是一種選擇。


要在活動中使用對話框,請按照以下方式進行操作:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     mContext = this;

     //using mContext here refering to activity context
     mBuilder = new AlertDialog.Builder(mContext);
     //...
     //rest of the code
     //...
}

要在片段中使用對話框,請按照以下方式進行:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View mRootView = inflater.inflate(R.layout.fragment_layout, container, false);
      mContext = getActivity();

      //using mContext here refering to fragment's hosting activity context
      mBuilder = new AlertDialog.Builder(mContext);
      //...
      //rest of the code
      //...
      return mRootView;
}

就是這樣^ _ ^





progressdialog