尝试在Application类的实例上调用getApplicationContext()会导致空对象引用错误。

3

我正在尝试在我的Android应用程序中进行一些网络操作。

导致错误的事件序列如下:

在我的片段中,如果不存在VolleySingleton类的实例,则会获取一个新的实例。

public static VolleySingleton getInstance() {
        if (vInstance == null) {
            vInstance = new VolleySingleton();
        }
        return vInstance;
    }

在创建VolleySingleton实例时,我创建了一个请求队列,并将其设置为Volley.newRequestQueue(myApplication.getContext());
    public class VolleySingleton {
    private static VolleySingleton sInstance = null;
    private ImageLoader imageLoader;
    private RequestQueue mRequestQueue;
    MyApplication myApplication = new MyApplication();

    private VolleySingleton() {
        mRequestQueue = Volley.newRequestQueue(myApplication.getAppContext());
        imageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
            private LruCache<String, Bitmap> cache = new LruCache<>((int)(Runtime.getRuntime().maxMemory()/1024/8));
            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            @Override
        public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        });
    }

    public static VolleySingleton getInstance() {
        if (sInstance == null) {
            sInstance = new VolleySingleton();
        }
        return sInstance;
    }

    public RequestQueue getRequestQueue() {
        return mRequestQueue;
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }
}

现在,myApplication仅是MyApplication类的一个实例,该类继承了Application,而getContext()只是在MyApplication的一个实例上调用getApplicationContext方法。以下是MyApplication类的代码:

public class MyApplication extends Application {

    private static MyApplication sInstance;
    public static final String API_KEY = "xxxxxxxx";

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance=this;
    }

    public static MyApplication getInstance() {
        return sInstance;
    }

    public Context getAppContext() {
        return sInstance.getApplicationContext();
    }


}

当我尝试return sInstance.getApplicationContext();时,出现了错误。

我已经在一个单独的测试项目中成功运行了相同的代码,所以我在这里感到困惑。

以下是我的logcat:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context com.xxxxxxxxx.chessgame.Models.MyApplication.getApplicationContext()' on a null object reference
            at com.xxxxxxxxx.chessgame.Models.MyApplication.getAppContext(MyApplication.java:28)
            at com.xxxxxxxxxx.chessgame.Networking.VolleySingleton.<init>(VolleySingleton.java:25)
            at com.xxxxxxxxx.chessgame.Networking.VolleySingleton.getInstance(VolleySingleton.java:42)
            at com.xxxxxxxx.chessgame.RecyclerViews.FragmentViewOne.onCreate(FragmentViewOne.java:95)
            at android.support.v4.app.Fragment.performCreate(Fragment.java:1763)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:913)
            at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:842)
            at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:859)
            at android.support.v4.app.FragmentStatePagerAdapter.setPrimaryItem(FragmentStatePagerAdapter.java:152)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441)
            at android.view.View.measure(View.java:17430)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:875)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:17430)
            at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:851)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
            at android.view.View.measure(View.java:17430)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.Act

你遇到了什么错误?请发布你的logcat。 - Bidhan
你在哪里将myApplication分配给MyApplication的实例? - Daniel Nugent
除了构造函数之外。我将在我的OP中包含整个VolleySingleton类。 - credo56
你在Fragment的哪个位置调用了 getInstance() 方法? - Daniel Nugent
在 onCreate 方法中:`public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } volleySingleton = VolleySingleton.getInstance(); requestQueue = volleySingleton.getRequestQueue();}` - credo56
您是否在清单文件中的<Application>标签中将您的MyApplication类声明为名称属性? - Pankaj
2个回答

6
请确保您在清单文件中的 应用程序 标签内声明了 android:name="packagename.MyApplication" 的 MyApplication 类。

1
谢谢,伙计。你让我的白天/黑夜变得美好 :) - O_o

2

MyApplication myApplication = new MyApplication();

看起来不对。

你可以更改VolleySingleton的构造函数和getInstance方法,接受Context作为参数。

事实上,Application有onCreate方法表明其生命周期由Android操作系统管理。就像你不应该new Activity()一样,你也不应该直接调用构造函数。你可以从例如Activity#getApplicationContext()获取Application的实例。


谢谢,这个很好地解决了问题,但下面的答案解释了MyApplication引起问题的真正原因。 - credo56

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接