Dialog throwing "Unable to add window — token null is not for an application” with getApplication() as context

前端 未结 28 1364
死守一世寂寞
死守一世寂寞 2020-11-22 08:42

My Activity is trying to create an AlertDialog which requires a Context as a parameter. This works as expected if I use:

AlertDialog.Builder builder = new Al         


        
相关标签:
28条回答
  • 2020-11-22 09:13

    Your dialog should not be a "long-lived object that needs a context". The documentation is confusing. Basically if you do something like:

    static Dialog sDialog;
    

    (note the static)

    Then in an activity somewhere you did

     sDialog = new Dialog(this);
    

    You would likely be leaking the original activity during a rotation or similar that would destroy the activity. (Unless you clean up in onDestroy, but in that case you probably wouldn't make the Dialog object static)

    For some data structures it would make sense to make them static and based off the application's context, but generally not for UI related things, like dialogs. So something like this:

    Dialog mDialog;
    
    ...
    
    mDialog = new Dialog(this);
    

    Is fine and shouldn't leak the activity as mDialog would be freed with the activity since it's not static.

    0 讨论(0)
  • 2020-11-22 09:13

    ***** kotlin version *****

    You should pass this@YourActivity instead of applicationContext or baseContext

    0 讨论(0)
  • 2020-11-22 09:15

    You've correctly identified the problem when you said "... for the AlertDialog() neither getApplicationContext() or getApplication() is acceptable as a Context, as it throws the exception: 'Unable to add window — token null is not for an application'"

    To create a Dialog, you need an Activity Context or a Service Context, not an Application Context (both getApplicationContext() and getApplication() return an Application Context).

    Here's how you get the Activity Context:

    (1) In an Activity or a Service:

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

    (2) In a Fragment: AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    Memory leaks is not a problem that is intrinsic to the "this" reference, which is an object's reference to itself (i.e. reference to the actual allocated memory for storing the object's data). It happens to any allocated memory for which the Garbage Collector (GC) is unable to free up after the allocated memory has outlived its useful lifespan.

    Most of the time, when a variable goes out of scope, the memory will be reclaimed by the GC. However, memory leaks can occur when the reference to an object held by a variable, say "x", persists even after the object has outlived its useful lifespan. The allocated memory will hence be lost for as long as "x" holds a reference to it because GC will not free up the memory for as long as that memory is still being referenced. Sometimes, memory leaks are not apparent because of a chain of references to the allocated memory. In such a case, the GC will not free up the memory until all references to that memory have been removed.

    To prevent memory leaks, check your code for logical errors that cause allocated memory to be referenced indefinitely by "this" (or other references). Remember to check for chain references as well. Here are some tools you can use to help you analyze memory use and find those pesky memory leaks:

    • JRockit Mission Control

    • JProbe

    • YourKit

    • AD4J

    0 讨论(0)
  • 2020-11-22 09:15

    Try getParent() at the argument place of context like new AlertDialog.Builder(getParent()); Hope it will work, it worked for me.

    0 讨论(0)
提交回复
热议问题