Объект класса Volley AppController, возвращающий значение null


Я создаю приложение, которое делает JsonObjectRequest и извлекает данные JSON из URL-адреса, используя сетевую библиотеку Volley для android.

AppController.java

public class AppController extends AppCompatActivity {

    public static final String TAG = AppController.class.getSimpleName();

    private RequestQueue mRequestQueue;

    private static AppController mInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mInstance = this;
    }

    public static synchronized AppController getInstance(){
        return mInstance;
    }

    public RequestQueue getRequestQueue(){
        if(mRequestQueue == null){
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
}

Метод в MainActivity.класс

private void makeJSONObjectRequest() {

        showDialog();

        JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
                urlJsonObj, (String) null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());

                try {

                    //Parsing JSON Object response
                    String name = response.getString("name");
                    String email = response.getString("email");
                    JSONObject phone = response.getJSONObject("phone");
                    String home = phone.getString("home");
                    String mobile = phone.getString("mobile");

                    jsonResponse = "";
                    jsonResponse += "Name: " + name + "nn";
                    jsonResponse += "Email: " + email + "nn";
                    jsonResponse += "Home: " + home + "nn";
                    jsonResponse += "Mobile: " + mobile + "nn";

                    txtResponse.setTag(jsonResponse);

                }

                catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }

                hideDialog();
            }
        },

        new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                VolleyLog.d(TAG+"Error:"+ volleyError.getMessage());
                Toast.makeText(getApplicationContext(), volleyError.getMessage(), Toast.LENGTH_SHORT).show();
                hideDialog();
            }
        });

        /*THE ERROR OCCURS HERE! */
        //adding request to the RequestQueue
        AppController.getInstance().addToRequestQueue(jsonObjReq);
    }

Это дает следующую ошибку:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.h8pathak.volleyjson.AppController.addToRequestQueue(com.android.volley.Request)' on a null object reference

Как я могу исправить этот код?

4 3

4 ответа:

Ваш AppController class должен расширить класс приложения вместо класса AppCompatActivity.

И не забудьте обновить свой Манифест. т.е.. Добавьте этот класс в свой AndroidManifest.xml с использованием атрибута name для тега <application>.

<application
        android:name=".AppController"/>

Нельзя использовать Activity как синглтон. Activity - это экран вашего приложения, и он может находиться в разных состояниях во время использования вашего приложения. Вы также пропускаете его, так как сохраняете статическую ссылку на него. Для вашей цели, если вам нужен контекст, расширьте Application вместо AppCompatActivity и зарегистрируйте его в своем Манифесте.

Я думаю, что вы должны создать "AppController" следующим образом:

public class AppController {

    private static AppController mInstance;

    private RequestQueue mRequestQueue;

    private static Context mCtx;

    private AppController(Context context){
        mCtx = context;
        mRequestQueue = getRequestQueue();
    }

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

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(@NonNull final Request<T> request) {
        getRequestQueue().add(request);
    }

    public <T> void addToRequestQueueWithTag(@NonNull final Request<T> request, String tag) {
        request.setTag(tag);
        getRequestQueue().add(request);
    }
}

И основная активность.класс

//adding request to the RequestQueue
AppController.getInstance(this).addToRequestQueue(jsonObjReq);

Не забудьте инициализировать объект RequestQueue. Вам нужно инициализировать RequestQueue внутри метода onCreate, Как вы можете видеть в примере:
(Иначе при вызове request.add(jsonObjectRequest) приложение попытается сослаться на объект null)

RequestQueue request;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //request qwe
    request= Volley.newRequestQueue(this);
}