深入了解 android 中的内部存储
deep look at Internal storage in android
我写了一个简单的应用程序,它只有一个 MainActivity
。
MainActivity
只有 ListView
和显示整数的简单 ArrayAdapter
。
当用户从菜单中单击 add
按钮时 - 在 listView
和 上又添加了一个值,所有整数都保存在文件 .
中
当用户单击 delete
时,正如预期的那样,从 listview
中删除了一个值
但是没有对文件做任何事情。
这是完整的代码:
public class MainActivity extends Activity {
private ArrayList<Integer> list;
private static final String fileName = "any_path";
private int ADD_ID = 0;
private int DELETE_ID = 1;
ArrayAdapter<Integer> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
load();
ListView view = new ListView(this);
setContentView(view);
adapter = new ArrayAdapter<Integer>(this,android.R.layout.simple_list_item_1, list);
view.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ADD_ID,1, "Add");
menu.add(0, DELETE_ID,0, "Delete");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == ADD_ID) { // if add was clicked
adapter.add(adapter.getCount());
save(); // SAVING HAPPENS HERE
return true;
} else if (item.getItemId() == DELETE_ID) {
list.remove(list.size()-1);
adapter.notifyDataSetChanged();
return true; // NOTHING DONE TO FILE
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onStop() {
super.onStop();
save();
}
private void save() {
JSONArray array = new JSONArray();
for (int el:list) {
array.put(el);
}
Writer writer = null;
try {
OutputStream out = this.openFileOutput(fileName, Context.MODE_PRIVATE);
writer = new OutputStreamWriter(out);
writer.write(array.toString());
} catch (IOException e) {}
try {
writer.close();
} catch (IOException e) {}
}
private void load() {
list = new ArrayList<Integer>();
StringBuilder data = new StringBuilder();
BufferedReader reader = null;
try {
InputStream in = this.openFileInput(fileName);
reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
data.append(line);
}
JSONArray array = (JSONArray)new JSONTokener(data.toString()).nextValue();
for (int i=0;i<array.length(); i++)
list.add(array.getInt(i));
} catch (Exception e) {}
}
}
一切正常,但我不明白如何神奇地从文件中删除值。
更准确地说:
1)用户点击add
五次,所以'0 1 2 3 4'将保存在文件中:
2) 用户点击了 delete
两次,所以列表将是 0 1 2
但 文件没有任何变化
3) 如果我重新启动应用程序,我会看到 0 1 2
,而不是 0 1 2 3 4
这是为什么?
您似乎应该将数据更新(重新加载)到 listview
并在删除后重新设置它,因为使用 adapter.notifyDataSetChanged();
您通知适配器,但数据已经存在,如果您删除它会起作用直接来自 listview
。
所以你应该直接重新加载数据。
希望对你有帮助。
更新:
我以为你想把它倒过来。我不知道你是否关闭了 InputStream
和 OutputStream
。通常是因为这样。
当您关闭应用程序时,也会在 onStop() 中调用 save():
public void onStop() {
super.onStop();
save();
}
所以当它包含 0,1,2,3 时,它会重新启动。
我写了一个简单的应用程序,它只有一个 MainActivity
。
MainActivity
只有 ListView
和显示整数的简单 ArrayAdapter
。
当用户从菜单中单击 add
按钮时 - 在 listView
和 上又添加了一个值,所有整数都保存在文件 .
中
当用户单击 delete
时,正如预期的那样,从 listview
中删除了一个值
但是没有对文件做任何事情。
这是完整的代码:
public class MainActivity extends Activity {
private ArrayList<Integer> list;
private static final String fileName = "any_path";
private int ADD_ID = 0;
private int DELETE_ID = 1;
ArrayAdapter<Integer> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
load();
ListView view = new ListView(this);
setContentView(view);
adapter = new ArrayAdapter<Integer>(this,android.R.layout.simple_list_item_1, list);
view.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, ADD_ID,1, "Add");
menu.add(0, DELETE_ID,0, "Delete");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == ADD_ID) { // if add was clicked
adapter.add(adapter.getCount());
save(); // SAVING HAPPENS HERE
return true;
} else if (item.getItemId() == DELETE_ID) {
list.remove(list.size()-1);
adapter.notifyDataSetChanged();
return true; // NOTHING DONE TO FILE
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onStop() {
super.onStop();
save();
}
private void save() {
JSONArray array = new JSONArray();
for (int el:list) {
array.put(el);
}
Writer writer = null;
try {
OutputStream out = this.openFileOutput(fileName, Context.MODE_PRIVATE);
writer = new OutputStreamWriter(out);
writer.write(array.toString());
} catch (IOException e) {}
try {
writer.close();
} catch (IOException e) {}
}
private void load() {
list = new ArrayList<Integer>();
StringBuilder data = new StringBuilder();
BufferedReader reader = null;
try {
InputStream in = this.openFileInput(fileName);
reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
data.append(line);
}
JSONArray array = (JSONArray)new JSONTokener(data.toString()).nextValue();
for (int i=0;i<array.length(); i++)
list.add(array.getInt(i));
} catch (Exception e) {}
}
}
一切正常,但我不明白如何神奇地从文件中删除值。
更准确地说:
1)用户点击add
五次,所以'0 1 2 3 4'将保存在文件中:
2) 用户点击了 delete
两次,所以列表将是 0 1 2
但 文件没有任何变化
3) 如果我重新启动应用程序,我会看到 0 1 2
,而不是 0 1 2 3 4
这是为什么?
您似乎应该将数据更新(重新加载)到 listview
并在删除后重新设置它,因为使用 adapter.notifyDataSetChanged();
您通知适配器,但数据已经存在,如果您删除它会起作用直接来自 listview
。
所以你应该直接重新加载数据。
希望对你有帮助。
更新:
我以为你想把它倒过来。我不知道你是否关闭了 InputStream
和 OutputStream
。通常是因为这样。
当您关闭应用程序时,也会在 onStop() 中调用 save():
public void onStop() {
super.onStop();
save();
}
所以当它包含 0,1,2,3 时,它会重新启动。