(1)android中的数据存储主要有五种方式:
第一种、sharedPreferences存储数据,
适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),解锁口 令密码等
核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data/<package name>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。 SharedPreferences本身是一 个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例,该方法中name表示要操作的xml文件名,第二个参数具体如下:
Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE: 指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE: 指定该SharedPreferences数据能被其他应用程序读,写
Editor有如下主要重要方法:
SharedPreferences.Editor clear():清空SharedPreferences里所有数据
SharedPreferences.Editor putXxx(String key , xxx value): 向SharedPreferences存入指定key对应的数据,其中xxx 可以是boolean,float,int等各种基本类型据
SharedPreferences.Editor remove(): 删除SharedPreferences中指定key对应的数据项
boolean commit(): 当Editor编辑完成后,使用该方法提交修改
下面是具体的demo,登录注册通过sharedPreferences保存注册数据到user.xml文件中,通过sharedPerferences的contains方法验证用户是否存在,截图如下
具体实现代码如下:
package com.example.shareperferencesdemo1; import android.app.Activity; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { EditText edtName, edtPwd; Button btnLogin, btnRegister; SharedPreferences sp; Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtName = (EditText) findViewById(R.id.editText1); edtPwd = (EditText) findViewById(R.id.editText2); btnLogin = (Button) findViewById(R.id.button1); btnRegister = (Button) findViewById(R.id.button2); //实例化sharedperferences对象 sp = getSharedPreferences("user", Activity.MODE_PRIVATE); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String uName=edtName.getText().toString(); String uPwd=edtPwd.getText().toString(); if(uName.equals("")||uPwd.equals("")){ Toast.makeText(MainActivity.this, "用户名或密码不能为空", 2000).show(); }else{ //如果sharedpreferences中用户名已经存在 if(sp.contains(uName)){ //调用sharedpferences对象的getString(键值对)方法判断是否存在用户 if(uPwd.equals(sp.getString(uName,uPwd))){ Toast.makeText(MainActivity.this, "登录成功",2000 ).show(); }else{ Toast.makeText(MainActivity.this, "登录失败",2000).show(); } } } } }); btnRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (edtName.getText().toString().equals("") || edtPwd.getText().toString().equals("")) { Toast.makeText(MainActivity.this, "用户名或者密码不能为空!", 2000).show(); } else { String name = edtName.getText().toString(); String pwd = edtPwd.getText().toString(); if (sp.contains(name)) { Toast.makeText(MainActivity.this, "用户已存在", 2000).show(); } else { //获取edit对象 editor = sp.edit(); //向user文件中添加用户信息键值对 editor.putString(name, pwd); //添加数据 editor.commit(); Toast.makeText(MainActivity.this, "注册成功", 2000).show(); } } } }); } }
(2)文件存储
文件如果不放在sdcrad中则存在data/data目录下,如果文件要放在SDCard中,则首先要判断SDCard是否存在,如果存在,要获取SDCard文件对象,代码为
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //存在的情况 //Environment.getExternalStorageState(),获取SDCard的状态 //获取sdcard的文件对象 File sdCard=Environment.getExternalStorageDirectory(); }
还需要在注册文件中声明对Sdcard的读写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
效果图
代码如下:
package com.example.filestoragedemo; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.RandomAccessFile; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView tvContext; private EditText edtContext; private Button btnWrite; private Button btnRead; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 关联控件 tvContext = (TextView) findViewById(R.id.txtContext); edtContext = (EditText) findViewById(R.id.edtContext); btnWrite = (Button) findViewById(R.id.btnWrite); btnRead = (Button) findViewById(R.id.btnRead); btnWrite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String str = edtContext.getText().toString(); try { writeFile(str); edtContext.setText(""); } catch (IOException e) { e.printStackTrace(); } } }); btnRead.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { String str=readFile(); tvContext.setText(str); } catch (IOException e) { e.printStackTrace(); } } }); } // 写入文件的方法 public void writeFile(String str) throws IOException { // 将文件写到sdcard中 // 首先判断sdcard是否存在 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 存在的情况 // 获取sdcard的文件对象 File sdCard = Environment.getExternalStorageDirectory(); // 创建文件 File file = new File(sdCard.getAbsolutePath() + "/abc.txt"); // 随机流 RandomAccessFile rf = new RandomAccessFile(file, "rw"); // 将文件指针放到末尾 rf.seek(file.length()); // 写入文件 rf.write(str.getBytes()); // 关闭随机流 rf.close(); } else { Toast.makeText(MainActivity.this, "请插入内存卡", 2000).show(); } } public String readFile() throws IOException { // 将文件写到sdcard中 // 首先判断sdcard是否存在 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 存在的情况 // 获取sdcard的文件对象 File sdCard = Environment.getExternalStorageDirectory(); // 创建文件 File file = new File(sdCard.getAbsolutePath() + "/abc.txt"); //将文件转化为字节流 FileInputStream fs = new FileInputStream(file); // 将字节流转化为字符流 BufferedReader bf = new BufferedReader(new InputStreamReader(fs)); StringBuffer sb = new StringBuffer(); String line = null; // 读取 while ((line = bf.readLine()) != null) { sb.append(line); } bf.close(); fs.close(); return sb.toString(); } else { Toast.makeText(MainActivity.this, "请插入内存卡", 2000).show(); return null; } } }
(3)sqlite 数据存储
SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧,SQLiteDatabase类为我们提供了很多种方法。
要使用sqlite数据存储需要创建一个继承于SQLiteOpenHelper的类,该类封装了sqlite和android之间的驱动,所以我们不用向在java中一样要加载数据库驱动。
下面用一个学生信息demo,来实现学生的增删改查,demo的界面如下
首先建一个student实体类,代码如下
package com.example.androidsqlitedemo; import java.io.Serializable; public class Student implements Serializable{ private int id; private String name; private String sex; private int age; public Student(){ } public Student(int id){ super(); this.id = id; } public Student(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public Student(int id, String name, String sex, int age) { super(); this.id = id; this.name = name; this.sex = sex; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
数据库操作类
package com.example.androidsqlitedemo; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MyDB extends SQLiteOpenHelper { public MyDB(Context context){ super(context, "myDB.db", null, 1); } public MyDB(Context context, String name, CursorFactory factory, int version) { super(context, "myDB.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { //建表 String sql="create table student(id Integer primary key not null,name varchar(20),sex varchar,age Integer)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } //根据学号验证学生是否存在 public Boolean isStudentExit(Student student){ SQLiteDatabase db = this.getWritableDatabase(); String sql="select * from student where id='"+student.getId()+"'"; Cursor cursor = db.rawQuery(sql, null); if(cursor.getCount()==0){ return false; }else{ return true; } } //添加数据 public void insertStudent(Student student){ SQLiteDatabase db = this.getWritableDatabase(); String sql="insert into student(name,sex,age) values (?,?,?)"; db.execSQL(sql,new Object[]{student.getName(),student.getSex(),student.getAge()}); db.close();//关闭数据库 } //删除数据 public void deleteStudent(Student student){ SQLiteDatabase db = this.getWritableDatabase(); String sql="delete from student where id=?"; db.execSQL(sql, new Object[]{student.getId()}); db.close(); } //修改学生信息 public void updateStudent(Student student){ SQLiteDatabase db = this.getWritableDatabase(); String sql="update student set name=?,sex=?,age=? where id=?"; db.execSQL(sql, new Object[]{student.getName(),student.getSex(),student.getAge(),student.getId()}); db.close(); } //查一个学生的信息 public Student getStudent(int id){ Student student=new Student(); SQLiteDatabase db = this.getWritableDatabase(); String sql="select * from student where id='"+id+"'"; Cursor cursor = db.rawQuery(sql, null); while(cursor.moveToNext()){ String name=cursor.getString(1); String sex=cursor.getString(2); int age=cursor.getInt(3); student.setId(id); student.setName(name); student.setSex(sex); student.setAge(age); } return student; } //查询所有学生的信息 public ArrayList<Student> getAllStudent(){ ArrayList<Student> list=new ArrayList<Student>(); SQLiteDatabase db = this.getWritableDatabase(); String sql="select * from student"; Cursor cursor = db.rawQuery(sql, null); while (cursor.moveToNext()) { int id=cursor.getInt(0); String name = cursor.getString(1); String sex = cursor.getString(2); int age = cursor.getInt(3); list.add(new Student(id,name, sex, age)); } return list; } }
主界面的后台代码
package com.example.androidsqlitedemo; import java.io.Serializable; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private EditText edtId,edtName,edtSex,edtAge; private Button btnAdd,btnDelete,btnUpdate,btnFind,btnFindAll; private MyDB mydata; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtId=(EditText) findViewById(R.id.edtId); edtName=(EditText) findViewById(R.id.edtName); edtSex=(EditText) findViewById(R.id.edtSex); edtAge=(EditText) findViewById(R.id.edtAge); btnAdd=(Button)findViewById(R.id.btnAdd); btnDelete=(Button)findViewById(R.id.btnDelete); btnUpdate=(Button)findViewById(R.id.btnUpdate); btnFind=(Button)findViewById(R.id.btnFind); btnFindAll=(Button)findViewById(R.id.btnFindAll); mydata=new MyDB(MainActivity.this); btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //edtId.setEnabled(false); if(edtName.getText().toString().equals("")||edtAge.getText().toString().equals("")||edtSex.getText().equals("")){ Toast.makeText(MainActivity.this, "学生信息不能为空", 2000).show(); }else{ String name=edtName.getText().toString(); String sex=edtSex.getText().toString(); int age=Integer.parseInt(edtAge.getText().toString()); //Log.i("key", age+""); Student student=new Student(name, sex, age); mydata.insertStudent(student); Toast.makeText(MainActivity.this, "添加成功", 2000).show(); edtAge.setText(""); edtName.setText(""); edtSex.setText(""); } } }); btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(edtId.getText().toString().equals("")){ Toast.makeText(MainActivity.this, "请输入要删除学生的学号", 2000).show(); }else{ int id=Integer.parseInt(edtId.getText().toString()); Student student=new Student(id); if(mydata.isStudentExit(student)){ mydata.deleteStudent(student); edtId.setText(""); Toast.makeText(MainActivity.this, "删除成功", 2000).show(); }else{ Toast.makeText(MainActivity.this, "要删除的学生不存在", 2000).show(); } } } }); btnUpdate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(edtId.getText().toString().equals("")){ Toast.makeText(MainActivity.this, "请输入要修改学生信息的学号", 2000).show(); }else{ int id=Integer.parseInt(edtId.getText().toString()); Student student=new Student(id); if(mydata.isStudentExit(student)){ if(edtAge.getText().toString().equals("")||edtName.getText().toString().equals("")||edtSex.getText().toString().equals("")){ Toast.makeText(MainActivity.this, "要修改的学生信息不能为空", 2000).show(); } else{ String name=edtName.getText().toString(); String sex=edtSex.getText().toString(); int age=Integer.parseInt(edtAge.getText().toString()); Student stu=new Student(id, name, sex, age); mydata.updateStudent(stu); Toast.makeText(MainActivity.this, "修改成功", 2000).show(); } }else{ Toast.makeText(MainActivity.this, "该学生不存在,请重新输入学号", 2000).show(); } } } }); btnFind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(edtId.getText().toString().equals("")){ Toast.makeText(MainActivity.this, "请输入要查找学生的学号", 2000).show(); }else{ int id=Integer.parseInt(edtId.getText().toString()); //Log.i("key", id+""); Student stu=new Student(id); if(mydata.isStudentExit(stu)){ Student student=mydata.getStudent(id); edtName.setText(student.getName().toString()); edtAge.setText(student.getAge()+""); edtSex.setText(student.getSex().toString()); }else{ Toast.makeText(MainActivity.this, "改学生不存在,请重新输入学号", 2000).show(); } } } }); btnFindAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ArrayList<Student> list=mydata.getAllStudent(); Bundle bundle=new Bundle(); //这里list里面存储的student要实现Serializable接口菜可以被传递 bundle.putSerializable("list", (Serializable)list); Intent intent=new Intent(MainActivity.this,StudentInfo.class); intent.putExtras(bundle); startActivity(intent); Log.i("list", "success"); } }); } }
传递参数后的第二个界面代码
package com.example.androidsqlitedemo; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.ListView; public class StudentInfo extends Activity { private ListView lvStudent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.student); lvStudent=(ListView) findViewById(R.id.lvStudent); Intent intent=getIntent(); ArrayList<Student> list =(ArrayList<Student>) intent.getSerializableExtra("list"); lvStudent.setAdapter(new MyAdapter(this, list)); } }
listView适配器代码
package com.example.androidsqlitedemo; import java.util.ArrayList; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends BaseAdapter { private Context context; private ArrayList<Student> list; public MyAdapter(Context context, ArrayList<Student> list) { super(); this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { ViewHolder holder; if(view==null){ holder=new ViewHolder(); view=LayoutInflater.from(context).inflate(R.layout.item, null); holder.txtID=(TextView) view.findViewById(R.id.tvID); holder.txtName=(TextView) view.findViewById(R.id.tvName); holder.txtSex=(TextView) view.findViewById(R.id.tvSex); holder.txtAge=(TextView) view.findViewById(R.id.tvAge); view.setTag(holder); } else{ holder=(ViewHolder) view.getTag(); } holder.txtID.setText(list.get(position).getId()+""); holder.txtName.setText(list.get(position).getName().toString()); holder.txtSex.setText(list.get(position).getSex().toString()); holder.txtAge.setText(list.get(position).getAge()+""); return view; } private final class ViewHolder{ TextView txtID; TextView txtName; TextView txtSex; TextView txtAge; } }
android与sqlite中游标cursor对象类似于dataset对象,其主要的方法有
1 c.move(int offset); //以当前位置为参考,移动到指定行 2 c.moveToFirst(); //移动到第一行 3 c.moveToLast(); //移动到最后一行 4 c.moveToPosition(int position); //移动到指定行 5 c.moveToPrevious(); //移动到前一行 6 c.moveToNext(); //移动到下一行 7 c.isFirst(); //是否指向第一条 8 c.isLast(); //是否指向最后一条 9 c.isBeforeFirst(); //是否指向第一条之前 10 c.isAfterLast(); //是否指向最后一条之后 11 c.isNull(int columnIndex); //指定列是否为空(列基数为0) 12 c.isClosed(); //游标是否已关闭 13 c.getCount(); //总数据项数 14 c.getPosition(); //返回当前游标所指向的行数 15 c.getColumnIndex(String columnName);//返回某列名对应的列索引值 16 c.getString(int columnIndex); //返回当前行指定列的值
(4)contentprovider存储数据
(5)网络存储数据