0

Pretty much all day today I've been trying to figure this out but I can't seem to get it right. I understand how to use the File-Output/Input-Stream. However since ArrayList is not an "int" I can't just pass my ArrayList through it. I gather that "serialization" converts my ArrayList to bytes, which can then be manipulated through the File-Output/Input-Stream. I CANNOT figure out how it works though. I stole the "Object-Input/Output-Stream" code from someone else, who seemed to be targeted towards the same goal as I was, but it doesn't work for me. I've looked at serialization in the Android Dev Docs, but cannot figure out exactly how it works.

Can someone please;

A) explain HOW serializing works and/or how to perform it, in more simple terms?

&

B) explain why the below code doesn't work (e.g. BEFORE I added all of the Object(in/out)putStream, my code populated the Listview dynamically and in real time, and NOW it doesn't do anything when the button is pushed, NOR does it load anything, NOR does it throw any errors).

also

C) is there an easier way to store this ArrayList so that it's persistent data.

package com.example.thepicker;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;

public class Settings extends Activity implements OnClickListener{


    EditText getit;
    ImageButton giveit;
    ListView thelist;
    ArrayList<String> items;
    ArrayAdapter<String> list;
    Intent pass;
    FileOutputStream persistout;
    FileInputStream persistin;
    ObjectOutputStream osistout;
    ObjectInputStream osistin;

    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings);

        items = new ArrayList<String>();
        list = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items);
        pass = new Intent(this,Main.class);
        getit = (EditText) findViewById(R.id.getit);
        giveit = (ImageButton) findViewById(R.id.giveit);
        thelist = (ListView) findViewById(R.id.thelist);


        try {
                persistin = openFileInput("FILENAME");
                osistin = new ObjectInputStream(persistin);
                items = (ArrayList<String>) osistin.readObject();
                osistin.close();
                persistin.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }



        thelist.setAdapter(list);
        list.notifyDataSetChanged();
        giveit.setOnClickListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();

        pass.putExtra("total", items);  
        this.startActivity(pass);

        try {
            persistout = openFileOutput("FILENAME", Context.MODE_PRIVATE);
            osistout = new ObjectOutputStream(persistout);
            osistout.writeObject(items);
            osistout.close();
            persistout.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


}



    @Override
    public void onClick(View v) {
    items.add(getit.getText().toString());
    list.notifyDataSetChanged();
}

}
Eric Anthony
  • 927
  • 1
  • 8
  • 15

1 Answers1

1

A) The serialization isn't your issue. You're doing it "right" as far as I can tell. I would STRONGLY suggest using sqlite instead of serialization, but that's because I'm a db nut.

B) You're creating a list towards the top

items = new ArrayList();

Then creating the adapter with that list. Its a variable reference. You're then deserializing your list AFTER you created the adapter. The adapter has a reference to the other list you created. Your items VARIABLE now points to a different list entirely. Do your adapter init after you deserialize, and it should work.

C) Not sure about "easier", but sqlite is "better".

You have major systemic issues with the design, though. You're doing all kinds of I/O in the main thread, which is a no-no. You're reading in onCreate, but saving in onPause, which should work, but is unbalanced (onCreate's yang is onDestroy. onResume goes with onPause). Not that it won't work, but its weird.

Keeping your List var local feels weird too, but looking at the Android code, as long as you don't redefine it (as you are now), the reference in your list should be the same.

Kevin Galligan
  • 16,159
  • 5
  • 42
  • 62
  • A/C) I'm looking into all different types of data storage, and DB seems to be what I'd be more apt to. I've looked at it and gotten scared but I don't mind learning. This project of mine, is honestly, a learning experience. – Eric Anthony Mar 18 '13 at 09:08
  • B) I see what you're saying. If I read you correctly, Instead of `list = new ArrayAdapter(this,android.R.layout.simple_list_item_1,items);` where it currently is, it should be AFTER the deserialization once `items` has been pulled from the `ObjectInputStream`. Correct? – Eric Anthony Mar 18 '13 at 09:12
  • D) If I've learned all screwed up please stop me now, before it get worse. I/O would be input/output? Are you talking about everything in the class, but before `onCreate`? I've seen it both ways and never understood what the difference was. The yin and yang of `onCreate` and `onDestroy` I knew about, I was just playing with the lifecycle to better understand it. I appreciate all your help. I will mark the answer when I get home and try everything out. Even though I can pretty much tell you are right. – Eric Anthony Mar 18 '13 at 09:21
  • @EricAnthony For SQLite, take a look at my answer about best practices: http://stackoverflow.com/questions/2493331/what-are-the-best-practices-for-sqlite-on-android/3689883#3689883. See associated blog post links. Also, here's a simple ORM tool: http://ormlite.com/. Just skip the "Helper" activities/services. They're unnecessary. Maintain a single Helper instance and you'll be OK (I did the original Android port. Have learned much since about managing db's). – Kevin Galligan Mar 20 '13 at 02:34
  • @EricAnthony openFileInput means you're reading a file from the local drive. That's input/output to disk. onCreate is a lifecycle method that gets called in the main/ui thread. That's a no no. Disk access can be slow. All apps use the disk, and the disk can only do one thing at a time. If some other app is going nuts with i/o, you'll freeze your UI. After 5 seconds, you'll get the ANR screen (Application Not Responding). If you've ever seen "Wait" and "OK" buttons on a dialog, that's why. Read about StrictMode: http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html – Kevin Galligan Mar 20 '13 at 02:37