2016-07-26 20 views
0

私のアプリケーションは競合状態が発生しているようですが、その理由はわかりません。最初にアプリケーションを開いたときにのみ発生します。エラーによると、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); 
    } 

メイン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のままであることを意味します。

mCtxの代わりにMainActivity.instanceを使用して、フィールドの現在の値を取得する必要があります。

+0

これは完全に機能しました。ありがとうございます。私は、クラスローダがどのように動作していたかについては考えていませんでした。問題を追跡することは不可能に近いものでした。頭を叩く時間を節約しました! – Ubarjohade

+0

クラスローダーの読み込み方法について考えないでください。Java変数は参照ではなく値であるため、「参照先」変数へのその後の変更は「参照元」変数に反映されません。 –