简体   繁体   中英

How can class.this in a callback can be null?

I have a Fragment. In this Fragment I run a http request on an json-rpc. To handle the result I have something like this in my Callback.

FragmentClass.this.getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do something
    } 
});

The problem is, sometimes i get a NullPointerException on the first line... My first intend was, that the fragment got detached to fast maybe because the user selects an other fragment while the request runs and so the

FragmentClass.this.getActivity();

has no activity and returns null. I enclose the whole thing with an if like this:

// New if:
if (FragmentClass.this.getActivity() != null) {

    FragmentClass.this.getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            // Do something
        } 
    });

}

But... Nothing... Now I get an NullPointerException on the if statement. it seems that

FragmentClass.this

is null.

How is that possible. I thought an instance will be hold until no code part needs it and the gc collects it...

Here is the stacktrace that logcat gives me. I have changed the package-name and the classnames. Line 192 is the line of the if statement.

09-18 10:49:36.915    3860-3860/de.unkown.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at de.unkown.app.camera.#FragmentClass$6.onError(FragmentClass.java:192)
            at de.unkown.app.webservice.JsonRpcService$10.onError(JsonRpcService.java:497)
            at    de.unkown.app.webservice.JsonRpcService$DefaultErrorListener.onErrorResponse(JsonRpcService.java:107)
                at com.android.volley.Request.deliverError(Request.java:577)
            at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:101)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)

Thank you for your help!

Artur

create a global variable Context context ;

than initialize the variable in on Create method:

context = get Activity();

than use it as:

context. runOnUiThread (new Runnable() {
    @Override
    public void run() {
        // Do something
    } 
});

hopefully this will help you.

getActivity() returns null in onCreate and onCreateView methods.
Use getActivity() inside onViewCreated . It is good to surround code using getActivity with a check - if (isAdded()) { } .

In your case you are getting null because, by the time you call FragmentClass.this.getActivity(), your fragment is no longer visible to the user, essentially onStop was already called.

To further add to my answer -
Suppose you are calling a method doSomething() on a fragment in which you are performing an AsyncTask . Then pass YourFragmentClass.this as a method parameter to doSomething(YourFragmentClass thiz) and use this object inside your doInBackground() and onPostExecute() methods instead of using YourFragmentClass.this, because YourFragmentClass.this returns null, because by the time AsynTask runs, your fragment would have moved to onPause or onStop.

Ok,

i changed in all asynchronous blocks the

FragmentClass.this.getActivity()

to

getActivity()

This seams to help. Please don´t ask me why... I thought this should be the same...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM