从另一个类引用时获取窗口抛出空指针异常

Posted

技术标签:

【中文标题】从另一个类引用时获取窗口抛出空指针异常【英文标题】:Get Window throws null pointer exception when referenced from another class 【发布时间】:2020-08-12 23:15:33 【问题描述】:

我在 android Studio 的 Fragment 中使用 PDFViewer。图书馆在这里找到:https://github.com/barteksc/AndroidPdfViewer

当我允许库处理所有触摸事件时,此库工作正常,但我想在 onSingleTapConfirmed 事件发生时隐藏我的活动 (SingleTouchImageViewActivity) 中的系统工具栏。由于 OnTouchListener 在另一个类 (DragPinchManager) 中,我无法在我的 Activity 中引用 Window 来标记全屏。我得到一个空指针异常。

2020-04-28 19:00:02.952 22265-22265/com.biggerbytes.gospeltruth E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.biggerbytes.gospeltruth, PID: 22265
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.Window.addFlags(int)' on a null object reference
    at com.biggerbytes.gospeltruth.SingleTouchImageViewActivity.hideSystemUI(SingleTouchImageViewActivity.java:1109)
    at com.biggerbytes.gospeltruth.SingleTouchImageViewActivity.runFullScreenCheck(SingleTouchImageViewActivity.java:900)
    at com.github.barteksc.pdfviewer.DragPinchManager.onSingleTapConfirmed(DragPinchManager.java:80)
    at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:316)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7073)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

这是 DragPinchManager 中的代码:

Context stivaContext;

@覆盖 公共布尔 onSingleTapConfirmed(MotionEvent e)

    SingleTouchImageViewActivity singleTouchImageViewActivity = new SingleTouchImageViewActivity();
    stivaContext = singleTouchImageViewActivity.getStivaContext();
    singleTouchImageViewActivity.hideSystemUI(stivaContext);
    return true;

这里是SingleTouchImageViewActivity中对应的代码:

Context stiva;    

 @Override
public View onCreateView(String name, Context context, AttributeSet attrs) 

    stiva = context;

    if(FullScreenMode) 
        hideSystemUI(stiva);
    


    public void hideSystemUI(Context context) 
    FullScreenMode = true;
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    if(Build.VERSION.SDK_INT < 19)  // lower api
        getWindow().getDecorView().setSystemUiVisibility(View.GONE);
     else 
        //for new api versions.
    //    View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        getWindow().getDecorView().setSystemUiVisibility(uiOptions);
    

    toolbarTop.setVisibility(View.GONE);
    toolbarBottom.setVisibility(View.GONE);

如何修复我的 nullPointerException 并在 SingleTapConfirmed 上隐藏我的导航? 谢谢!

更新:这是我所做的。我在 SingleTouchImageViewActivity 中设置了一个名为 stiva 的上下文变量。我在调用 onCreateView 时设置它。 pdf加载后,我单击我的pdf。 DragPinchManager 调用一个方法从 SingleTouchImageViewActivity 获取上下文,然后调用 hideSystemUI(stiva),传入它在 pdf 触发单击事件时从 SingleTouchImageViewActivity 接收到的上下文。 出于某种原因,当 DragPinchManager 尝试引用 stiva 时,它为空。你能帮我解决这个问题吗?

另外,我不确定如何使用传递给 hideSystemUI() 的上下文。

这就是我的想法,但我想我还差得远……

SingleTouchImageViewActivity.context.getWindow().getDecorView().setSystemUiVisibility(View.GONE);

【问题讨论】:

new SingleTouchImageViewActivity() -- 从不自己创建活动实例。无论对象包含您的 onSingleTapConfirmed() 方法,都需要将现有的 SingleTouchImageViewActivity 实例传递给它,这样您就可以在字段中保留它,然后在其上调用方法。 @CommonsWare 能否举个例子说明如何传入现有的 SingleTouchImageViewActivity 实例? In this sample 来自this book,我的活动将LayoutInflater 传递给我的ColorAdapter。我可以很容易地让我的活动将活动本身传递给我的ColorAdapter,并且ColorAdapter 可以在活动本身上调用getLayoutInflater() @CommonsWare 你能再看一下这个问题吗?我更新了它以及我的代码。我不确定是否需要传递活动本身或是否需要传递上下文。谢谢你的帮助。我真的很感激。 您的代码似乎没有传递任何东西。相反,您似乎正在通过将Context 放入static 字段来创建可能的内存泄漏。据推测,您的活动正在创建DragPinchManager 的实例。如果是这样,请将Activity 通过其构造函数传递给DragPinchManager,例如how this constructor accepts a LayoutInflater 【参考方案1】:

正如@CommonsWare 所说,永远不要自己创建活动实例。

这个崩溃是因为你使用了窗口对象而你的活动没有窗口!

要解决此问题,请使用 Intent 启动您的活动

@Override
public boolean onSingleTapConfirmed(MotionEvent e) 
    Intent i = new Intent(this, SingleTouchImageViewActivity.class);

    startActivity(i);

然后在onCreateSingleTouchImageViewActivity内部调用hideSystemUI方法

【讨论】:

以上是关于从另一个类引用时获取窗口抛出空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

为啥非空列表会抛出空指针异常?

为啥grails在第一次访问hasMany关系时抛出空指针异常?

Play 2.4 Finder 抛出空指针异常

注册方法在我的控制器类中抛出空指针异常

JSONObject 创建抛出空指针异常

SearchView 展开抛出空指针异常