2016-07-26 52 views
0

我的申請似乎遇到競爭條件,我不確定原因。它只發生在我第一次打開應用程序時。根據錯誤,MainActivity中的靜態變量實例爲空,但在啓動服務之前設置了變量。看起來服務在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); 
    } 

主要acivity

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
private static Context mCtx = MainActivity.instance; 

被加載的類時,該被初始化。它取決於當時的字段值,而不是隨後使用它的值。

這意味着如果在類加載器加載NetworkCalls時它是null,它將保持null,直到它被重新分配爲止。

您需要使用MainActivity.instance而不是mCtx來獲取字段的當前值。

+0

這很好,謝謝。我不會想到類加載器是如何工作的,而且幾乎不可能跟蹤這個問題。節省了我幾個小時的頭痛! – Ubarjohade

+0

不要考慮類加載器是如何加載的:​​請記住,Java變量是值而不是引用,因此對「引用」變量的後續更改不會反映在「引用」變量中。 –