2013-08-15 2 views
0

ArrayList를 확장하는 사용자 정의 객체에 이벤트의 영구 로그를 유지하는 Android 앱이 있습니다. 싱글 톤으로 유지되므로 다양한 활동이 모두 동일한 로그를 가리 킵니다. 주 활동은 onResume의 목록을 다시로드합니다.새 인스턴스를 만들지 않고 디스크에서 Java 객체를 다시로드 하시겠습니까?

문제는 로그를 다시로드 할 때 ArrayAdapter와 같은 모든 UI 요소가 참조를 잃어 버리고 다시 설정해야한다는 것입니다. 그것은 작동합니다. 그러나 그것은 많은 일처럼 보입니다.

원래 개체의 인스턴스에 개체를 다시로드 할 수 있도록하려면 어떻게해야합니까? 다시 설치하지 않아도됩니다. 싱글 톤을 사용하면 쉽게 열심히하지 않아야합니다.

나는 통과를 통해 모든 문제를 알고 있습니다. 그러나 나는 단지 그 주위에 내 머리를 얻을 수 없습니다.

자바가 제 첫 번째 언어가 아닙니다 ... 감사합니다.

활동에서 onCreate :

dataLog = DataLog.getInstance(); 
logView = (ListView) findViewById(R.id.logView); 
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog);   
logView.setAdapter(dataLogAdapter); 

활동 onResume :

dataLog = Persister.recoverLog(this, "datalog.dat"); 
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog); 
logView.setAdapter(dataLogAdapter); 

Persister :

public static DataLog recoverLog(Context context, String fileName){ 
File file = context.getFileStreamPath(fileName); 
DataLog obj = new DataLog(); 

if(file.exists() && file.length()>0){ 
    FileInputStream fis = null; 
    ObjectInputStream ois = null; 
    try { 
     fis = new FileInputStream(file); 
     ois = new ObjectInputStream(fis); 
     obj = (DataLog) ois.readObject(); 
     ois.close(); 
     fis.close(); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } catch (ClassNotFoundException ex) { 
     ex.printStackTrace(); 
    } 
} 
return obj; 
} 

데이터 로그 :

public class DataLog extends ArrayList<String> implements Serializable { 
    private static final long serialVersionUID = 0L; 
    public DataLog() {} 

    private static DataLog _instance; 
    public static DataLog getInstance() { 
     if(_instance==null){ 
      _instance = new DataLog(); 
     } 
     return _instance; 
    } 

    public boolean add(String entry) { 
     super.add(entry); 
     return true; 
    } 

    public void add(int index, String entry) { 
     if (index > 0) 
      super.add(index, entry); 
     else 
      super.add(entry); 
    } 

    public void clear() { 
     super.clear(); 
    } 

} 
+2

그것은 바이 패스 reference_와 _problem 수 없다 자바 패스별로 값이다. 객체를 직렬화하는 대신 String 항목을 하나씩 직렬화하는 것이 어떻습니까? –

+0

"싱글 톤"은 실제로 싱글 톤을 사용하는 경우 더 쉽게 만들 수 있습니다. Persister로 새로운 인스턴스를 다시 만들므로 물론 모든 객체가 새 참조를 인식하도록해야합니다. –

+0

@JasonC 바로 그 대답에 대해 설명했습니다. –

답변

0

데이터 로그는 진정한 싱글 톤이 아닙니다. 만약 그렇다면 처음 만들어진 후에는 새로운 참조가 만들어지지 않을 것입니다.

이 :

dataLog = Persister.recoverLog(this, "datalog.dat"); 

반환 안된다 Datalog 그러나 어떤 내부 데이터 DataLog 용도 (AN 문자열의 ArrayList를)과

DataLog 내에서 호출되어야 그럼 주위 데이터 로그 인스턴스를 전달한다. 재 할당하면 문제가 발생합니다. 데이터 로그를 다시로드하면 DataLog의 배열 인스턴스에 의존하는 구조를 다시로드해야합니다.

필요한 경우 onResumeDataLog 데이터를 다시로드 핸들,하지만 그렇게처럼 수행

DataLog.getInstance().load(); 

그래서 데이터 로그가 재 할당되지 않습니다 것을. 그게 핵심이야. DataLog는 데이터를 둘러싼 래퍼입니다. DataLog의 내부 상태가 변경되면 DataLog에 대한 참조가 손실됩니다.

여기의 예이다 :

public class DataLog implements Serializable { 
    //internalize this data. 
    private ArrayList<String> data; 
    private static final long serialVersionUID = 0L; 

    //singleton's constructor should be private. 
    private DataLog() {} 

    private static DataLog _instance; 
    public static DataLog getInstance() { 
     if(_instance==null){ 
      _instance = new DataLog(); 
     } 
     return _instance; 
    } 

    public ArrayList<String> getData(){ 
     //copy this if you're worried about it being modified. 
     //DO NOT pass this reference around. Pass a reference to data log, 
     //reload GUI relying on this reference as needed. 
     return data; 
    } 

    public void load(){ 
     data = //reload string array from disk. 
    } 

    public boolean add(String entry) { 
     super.add(entry); 
     return true; 
    } 

    public void add(int index, String entry) { 
     if (index > 0) 
      data.add(index,entry); 
     else 
      data.add(entry); 
    } 

    public void clear() { 
     data.clear(); 
    } 
} 
+1

조심성; 'getInstance()'에서 "recoverLog()"를 "필요할 때마다"호출하면, 그것은'instance_'가 바뀔 수 있음을 의미합니다. 괜찮 았지만, 당신은 getInstance() 대신에 getInstance 인스턴스 자체가 오래되었거나 더 이상 유효하지 않은 참조를 고수하지 않도록합니다. –

+0

감사합니다. @JasonC 자신을 더 명확하게 설명했습니다. 잘 잡으세요! 나는 사람들이 코멘트에 upvotes에 대한 담당자를 가지고 있었으면 좋겠어 ... –

+1

Ah. 그건 의미가 있습니다. 그래서 문제는 ArrayList를 확장 할 수 없으며 대신 내부 참조로 영향을주지 않고 조작 할 수있는 ArrayList를 포함합니다. 나는 그것이 그와 같을 것이지만 세부 사항에서 길을 잃었을 것으로 의심했다. 감사. – PrecisionPete

관련 문제