2016-12-01 60 views
0

我想從一個類中取數據,把它放在一個單例中,然後繼續訪問另一個類中的數據。單身Android不能訪問數據

這是我的單例:

public class DataTransferrer { 
    private static DataTransferrer instance = null; 

    private ArrayList<Transients> transientList; 

    private DataTransferrer(){ 
     transientList = new ArrayList<>(); 
    } 

    public static synchronized DataTransferrer getInstance(){ 
     if(instance == null) {instance = new DataTransferrer();} 
     return instance; 
    } 

    public ArrayList<Transients> getTransients(){return this.transientList;} 

    public void setTransients(ArrayList<Transients> t){transientList = t;} 

    public void printAll(){ 
     for(Transients t : transientList){ 
      Log.d("DEBUG DA",t.getDa().toString()); 
     } 
    } 

    } 

這是我的方法,該方法將數據添加到一個arrayList,然後設置爲arrayList單身內,然後被其他地方使用:

public class JSONParser { 

    // URL to get contacts JSON 
    private static String url = "http://pi.cs.oswego.edu/~lpatmore/getAllTransients.php"; 

    ArrayList<Transients> transientList; 

    private Transients t; 

    public JSONParser(){ 
     transientList = new ArrayList<>(); 
    } 

    public void execute(){ 
     new GetTransients().execute(); 
    } 
    /** 
    * Async task class to get json by making HTTP call 
    */ 
    private class GetTransients extends AsyncTask<Void, Void, Void> { 

     protected Void doInBackground(Void... arg0) { 
      HttpHandler sh = new HttpHandler(); 

      // Making a request to url and getting response 
      String jsonStr = sh.makeServiceCall(url); 

      Log.d(TAG, "Response from url: " + jsonStr); 

      if (jsonStr != null) { 
       try { 

        Log.d(TAG, "NOT NULL DEBUG"); 
        JSONObject jsonObj = new JSONObject(jsonStr); 

        // Getting JSON Array node 
        JSONArray transients = jsonObj.getJSONArray("result"); 

        // looping through All Transients 
        for (int i = 0; i < transients.length(); i++) { 
         JSONObject c = transients.getJSONObject(i); 

         String author = c.getString("author"); 
         String transientId = c.getString("transientId"); 
         String dateAlerted = c.getString("dateAlerted"); 
         String datePublished = c.getString("datePublished"); 
         float right_asencsion = (float) c.getDouble("right_asencsion"); 
         float declination = (float) c.getDouble("declination"); 

         t = new Transients(author, transientId, dateAlerted, datePublished, right_asencsion, declination); 

         // adding trans to trans list 
         transientList.add(t); 
        } 
        DataTransferrer.getInstance().setTransients(transientList); 
        DataTransferrer.getInstance().printAll(); 
       } catch (final JSONException e) { 
        Log.e(TAG, "Json parsing error: " + e.getMessage()); 
       } 
      } else { 
       Log.e(TAG, "Couldn't get json from server."); 
      } 
      return null; 
     } 

    } 
} 

而我嘗試在另一個類中訪問它,例如:

for(int i = 0; i <  DataTransferrer.getInstance().getTransients().size(); i++){ 
     System.out.println("DEBUG ADDED TRANSIENT"); 
     Float ra = DataTransferrer.getInstance().getTransients().get(i).getR(); 
     Float dec = DataTransferrer.getInstance().getTransients().get(i).getD(); 
     transients.add(new Transient("Transient", names[i], GeocentricCoordinates.getInstance(ra, dec))); 
    } 

每當我調試它時檢查在其他類中看到的內容,我試圖訪問arraylist,但是在另一個類中,它就像從未將數組列表添加到getTransients()方法中。

我在Eclipse中測試了這個確切的設置,它完美的工作,但不是在Android Studio中。

+0

你可以添加你有'for'循環的全部方法嗎? – developer

+0

你在那裏創建了'transientList'? – developer

+0

@javaguy我將其餘的代碼添加到for循環方法,我實際上添加了整個類 – LJP1203

回答

0

我在Eclipse中測試了這個確切的設置,它完美的工作,但不在 Android Studio。

基本上,你擁有多線程問題即你DataTransferrer類不是線程安全的,這是造成問題,即,有多個線程之間的競爭條件和你的單身instance實際上不是單(多對象正在爲DataTransferrer類創建)。

所以,當你從一個線程調用setTransients(),它實際上是存儲在TransientsDataTransferrer一個instance,然後當你從不同的線程的DataTransferrer試圖retieve的Transients它使用不同的instance(對象)。

您可以爲您的DataTransferrer類線程安全的單一實例,如下圖所示:

public class DataTransferrer { 

     private static final DataTransferrer instance = new DataTransferrer(); 

     private ArrayList<Transients> transientList = new ArrayList<>(); 

     //private constructor, so instantiation NOT allowed 
     private DataTransferrer() {} 

     public static synchronized DataTransferrer getInstance(){ 
      return instance; 
     } 

     public ArrayList<Transients> getTransients(){ 
      return this.transientList; 
     } 

     public void setTransients(ArrayList<Transients> t){ 
      transientList = t; 
     } 

     public void printAll(){ 
      for(Transients t : transientList){ 
       Log.d("DEBUG DA",t.getDa().toString()); 
      } 
     } 
} 

另外,還要注意在上面的代碼,instance將在啓動(初始化)時急切地創建當您撥打setTransientsgetTransients時,會使用相同的instance(單身人士)。如果您需要長時間創建instance,您可以查看here,而不是急於創建。