上下文服务竞争条件

时间:2016-07-26 19:39:37

标签: java android android-service

我的申请似乎遇到了竞争条件,我不确定为什么。它只在我第一次打开应用程序时发生。根据错误,MainActivity中的静态变量实例为null,但我在启动服务之前设置了变量。似乎服务在onCreate在活动中完成之前就开始运行,但我不相信这是可能的。有什么想法发生了什么?

错误消息

E/AndroidRuntime: FATAL EXCEPTION: Timer- 

java.lang.NullPointerException                                                              
at NetworkCalls.getRequestQueue(NetworkCalls.java:42)                                                             
at NetworkCalls.addToRequestQueue(NetworkCalls.java:48)                                                                     
at NetworkCalls.createLocationPost(NetworkCalls.java:72)                                                                   
at StaticMethods.handleWarnings(StaticMethods.java:84)                                                                    
at LocationService.checkInPost(LocationService.java:73)                                                                     
at LocationService$1.run(LocationService.java:66)                                                                     
at java.util.Timer$TimerImpl.run(Timer.java:284)

网络类

public class NetworkCalls {
    private static NetworkCalls singleton;
    private RequestQueue mRequestQueue;
    private static Context warningCtx = WarningActivity.instance;
    private static Context mCtx = MainActivity.instance;

    private NetworkCalls() {
    }

    public static synchronized NetworkCalls getInstance() {
        if (singleton == null) {
            singleton = new NetworkCalls();
        }
        return singleton;
    }

    private RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {

            //Problem here is that mCtx is null
            if(mCtx == null){
                Log.e("Error", "It's FUBAR");
            }else {
                Log.e("Error", "It's Okay");
            }
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    private <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public void createLocationPost(LocationData locationData) {
        String url = "http://httpbin.org/post";
        HashMap<String, String> params = new HashMap<>();
        params.put("Token", "key");

        JsonObjectRequest jsObj = new JsonObjectRequest(url, new JSONObject(params), new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    Log.i("NetworkCalls Successful", response.getJSONObject("json").toString());
                } catch (JSONException ex) {
                    Log.i("Parsing response", "Unable to get json string");
                }
                // On Response recieved
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("NetworkCalls Error", error.toString());
            }
        });
        addToRequestQueue(jsObj);
    }

主要活动

public class MainActivity extends AppCompatActivity {

public static MainActivity instance = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#000000"));
    getSupportActionBar().setBackgroundDrawable(colorDrawable);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);


        instance = MainActivity.this;
            startService(new Intent(getBaseContext(), QueuePostService.class));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

private static Context mCtx = MainActivity.instance;

加载类时会初始化它。它取当时的字段值,而不是在您随后使用它时。

这意味着如果类加载器加载null时为NetworkCalls,则在重新分配之前它仍为null

您需要使用MainActivity.instance代替mCtx来获取字段的当前值。