在一个空对象引用上调用getApplicationContext()

20
我运行应用程序时总是会出现这个错误:java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference。我看到了其他答案,但我不明白如何使用那些答案,我理解存在一些与上下文有关的问题,因为没有通过Activity进行调用,所以我也尝试传递Activity上下文但没有成功... 这是我的代码: 编辑 我已经按照您的建议更新了代码(将上下文作为参数传递给Distance类和MySingleton类...),但仍然无法解决问题。
public class MainActivity extends AppCompatActivity {

    private Button b;
    private TextView t;
    private LocationManager locationManager;
    private LocationListener listener;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        t = (TextView) findViewById(R.id.textView);
        b = (Button) findViewById(R.id.button);

        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);


        listener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Log.d("Co", "onLocationChanged");
                Distance distance=new Distance();
                t.setText("\n " + location.getLongitude() + " " + location.getLatitude()+"\n "+distance.getDistance(location));

                Location l2=new Location("");
                
                //float distance=location.distanceTo(l2);
                Log.d("Co", String.valueOf(distance));
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle)   {

            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {

                Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(i);
            }
        };

        configure_button();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 10: {
                configure_button();
                Log.d("Co", "premmsioenChecks");

            }
            break;
            default:
                break;
        }
    }

    public void configure_button(){
        // first check for permissions
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.INTERNET}
                        ,10);
                Log.d("Co", "premmsioen");

            }
            return;
        }
        // this code won't execute IF permissions are not allowed, because in the line above there is return statement.
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //noinspection MissingPermission


                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
                Log.d("Co", "onClick");
                Location l2=new Location("");
                

            }
        });
    }

}


public class Distance   {

static  String url = "";
static String result="";

public  String getDistance(Location location,Context context) {

    Log.d("app","getDistance");






            String origins=location.getLatitude()+","+location.getLongitude();
            
            url="https://maps.googleapis.com/maps/api/distancematrix/json?&origins="+origins+"&destinations="+destinations;
            Log.d("URL",url);
            JsonObjectRequest jsObjRequest = new JsonObjectRequest

                    (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                        @Override
                        public void onResponse(JSONObject response) {
                            Log.d("app","onRespone");

                            String distance=getText(response);
                            if (distance.contains("Error")) {
                                result=distance;
                                return;
                            }
                            else {
                                if (distance.contains("km")) {
                                    int meters = Integer.parseInt(distance.replaceAll("[\\D]", "")) * 1000;
                                   result= "The distance is " + meters + " meters";
                                    return;
                                }
                                Log.d("7", String.valueOf(Integer.parseInt(distance.replaceAll("[\\D]", ""))));

                                result= "The distance is " + distance;
                            }



                        }
                    }, new Response.ErrorListener() {

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.d("app","Error Respone");

                        }
                    }
                    );
            MySingleton.getInstance(context).addToRequestque(jsObjRequest);
    return result;
        }




public  String getText(JSONObject response)
{
    String  text="";
    try {

        JSONArray rows = response.getJSONArray("rows");
        Log.d("1", rows.toString());
        if(rows.toString().contains("[]"))  return text="Error";
        JSONObject elements = rows.getJSONObject(0);
        Log.d("2", elements.toString());
        rows = elements.getJSONArray("elements");
        Log.d("3", rows.toString());
        elements  = rows.getJSONObject(0);
        Log.d("4", elements.toString());
        Log.d("Error1","Error is @"+elements.getString("status"));
        if( elements.getString("status").contains("OK"))
        {
            JSONObject d = elements.getJSONObject("distance");
            Log.d("5", d.toString());
            text = d.getString("text");
        }
        else {
            Log.d("Error2", elements.getString("status"));
            text = "Error-" + elements.getString("status");
        }

    }
    catch (JSONException e)
    {
        text="Some error ocuerd";
    }
    return text;
}


}


public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue requestQueue;
    public static Context mCtx;
    private MySingleton(Context context)
    {
        mCtx=context;
        requestQueue= getRequestQueue();
    }

    public RequestQueue getRequestQueue() {
        if(requestQueue==null) {
            requestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return requestQueue;
    }
    public static synchronized MySingleton getInstance(Context context)
    {
        if(mInstance==null)
        {
            mInstance=new MySingleton(context);
        }
        return mInstance;
    }
    public <T> void addToRequestque(Request<T> request)
    {
        requestQueue.add(request);
    }

}

这是logcat日志

06-24 16:19:26.771 25300-25300/com.example.elicahi.gateor D/Co: onClick
06-24 16:19:27.556 25300-25300/com.example.elicahi.gateor D/Co: onLocationChanged

06-24 16:19:27.579 25300-25300/com.example.elicahi.gateor D/AndroidRuntime: Shutting down VM
06-24 16:19:27.579 25300-25300/com.example.elicahi.gateor E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.example.elicahi.gateor, PID: 25300
                                                                            java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
                                                                                at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:107)
                                                                                at com.example.elicahi.gateor.MySingleton.getRequestQueue(MySingleton.java:24)
                                                                                at com.example.elicahi.gateor.MySingleton.<init>(MySingleton.java:19)
                                                                                at com.example.elicahi.gateor.MySingleton.getInstance(MySingleton.java:32)
                                                                                at com.example.elicahi.gateor.Distance.getDistance(Distance.java:79)
                                                                                at com.example.elicahi.gateor.MainActivity$1.onLocationChanged(MainActivity.java:54)
                                                                                at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:285)
                                                                                at android.location.LocationManager$ListenerTransport.-wrap0(LocationManager.java)
                                                                                at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:230)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:148)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

请检查 MySingleton.java 文件中的第 24 行代码 getRequestQueue() - Madhukar Hebbar
这行代码有问题:requestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); 你的 mCtx 是空的。 - Madhukar Hebbar
我理解了这一点,所以我将MainActivity上下文传递给了MySingleton,但我仍然得到相同的错误... - user5209063
7个回答

18
public class Distance extends Application

请不要随意扩展类,只是因为您认为这样可以清除编译器错误。在此处,您没有有效的Application子类,并且没有正确使用它。

步骤1:从Distance中删除extends Application

步骤2:让getDistance()Context作为参数,并使用MySingleton

步骤3:让MainActivitygetApplicationContext()作为Context传递给getDistance()


我已经做过了,但是我从我的代码中删除了它。无论如何,我再试一次,还是得到了同样的错误。 - user5209063
嘿,我更新了我的代码,就像你回答我的那样...问题是什么?我仍然得到相同的错误。 - user5209063
@user5209063:你需要确定如何将null传递到MySingleton构造函数中。 - CommonsWare
谢谢,我不知道发生了什么,但我只是在Distance类的开头添加了这个Log Log.d("MySingleton",context.toString());,然后编译它,它就可以工作了...奇怪,无论如何非常感谢。 - user5209063
你应该放置代码以进行澄清... - J. M.
显示剩余2条评论

1

for kotlin, you can use this:

requireNotNull(this.activity).application

0
对于在使用 Flutter Firebase 云消息传递(FCM)时遇到此错误的人,可能是在 pubspec.yaml 中有一个软件包引起了问题。
在我的情况下,keyboard_visibility 与 FCM 冲突。我不得不用 flutter_keyboard_visibility 替换它。

0

我遇到了这个问题,后来发现我在模拟器上运行的是默认预览而不是实际应用程序。


0
私有上下文 mContext;
private Activity mActivity;

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if (getActivity() == null) {
        return;
    }
    else
        {
        mActivity = getActivity();
    }
}

0
像之前的答案所说(CommonsWare),请这样做并放置:
Context context; // before onCreate in MainActivity

context = getApplicationContext();  // in onCreate in MainActivity

最好将其作为参数传递,而不是声明为可能为空的字段。这样做并没有真正增加任何东西。 - Ben Neill

0

这并不是一个真正的答案,而只是一个想法。

我也遇到了同样的问题(这就是我来到这个问题的原因),我的问题其实非常简单。我在设置单例模式中的私有上下文之前,正在尝试设置RequestQueue。

  private MySingleton(Context context) {
    ctx = context; // queue = getRequestQueue();    <--- queue first but it needs context.
    queue = getRequestQueue();    // ctx = context;   <--- ctx being set here. queue can't find context.
 }

public synchronized static MySingleton getInstance(Context context) {
    if (instance == null) {
        instance = new MySingleton(context);
    }
    return instance;
}

private RequestQueue getRequestQueue() {
    if (queue == null) {
        queue = Volley.newRequestQueue( ctx.getApplicationContext() ); // <--- Here is the crash;
    }
    return queue;
}

此外,在发现这个问题之前,我确保上下文在作为参数传递时不为空。这意味着问题必须出现在MySingleton代码中的某个地方。
// This code is run before MySingleton.getInstance() wherever it is in your app;
Context testParameter = getBaseContext();
Log.d("DEBUG_CONTEXT", testParameter.toString() );

所以我只是分享我的问题,希望它能给你带来一些想法。祝好运。


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