简体   繁体   English

回调中的class.this如何可以为null?

[英]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. 在此片段中,我在json-rpc上运行一个http请求。 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 问题是,有时我在第一行上收到NullPointerException ...我的初衷是,该片段被快速分离,可能是因为用户在请求运行时选择了另一个片段,所以

FragmentClass.this.getActivity();

has no activity and returns null. 没有活动,并返回null。 I enclose the whole thing with an if like this: 我将整个事情用if括起来:

// 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. 但是...什么都没有...现在我在if语句上得到了NullPointerException。 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... 我以为实例将一直保持到没有代码部分需要它并且gc收集它为止。

Here is the stacktrace that logcat gives me. 这是logcat给我的stacktrace。 I have changed the package-name and the classnames. 我已经更改了包名和类名。 Line 192 is the line of the if statement. 第192行是if语句的行。

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 ; 创建一个全局变量Context上下文;

than initialize the variable in on Create method: 比在Create方法上初始化变量:

context = get Activity(); 上下文= 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. getActivity()onCreateonCreateView方法中返回null。
Use getActivity() inside onViewCreated . onViewCreated使用getActivity() It is good to surround code using getActivity with a check - if (isAdded()) { } . 最好将getActivity与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. 在您的情况下,您会得到null,因为在您调用FragmentClass.this.getActivity()时,您的片段不再对用户可见,实际上已经调用了onStop。

To further add to my answer - 为了进一步增加我的答案-
Suppose you are calling a method doSomething() on a fragment in which you are performing an AsyncTask . 假设您正在执行AsyncTask的片段上调用方法doSomething()。 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. 然后将YourFragmentClass.this作为方法参数传递给doSomething(YourFragmentClass thiz)并在doInBackground()onPostExecute()方法中使用此对象,而不要使用YourFragmentClass.this,因为YourFragmentClass.this返回null,因为在AsynTask运行时,您的片段将移至onPause或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... 请不要问我为什么...我认为应该一样...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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