Android中数据存储和访问方式

本文详细介绍了Android中五种数据存储和访问方式:文件存储、SharedPreferences、SQLite数据库、ContentProvider以及网络访问。文件存储需要注意权限问题;SharedPreferences使用XML保存配置参数;SQLite通过SQL语句或专用方法进行数据操作;ContentProvider用于数据共享;网络访问涉及Socket通信和HTTP请求,网络操作通常在子线程中执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android中数据存储和访问方式一般有5种:

1,文件

2,SharedPreferences

3,SQLite数据库

4,ContentProvider

5,网络


一、文件

1-1,写入文件到手机

	private void writeFile(String filename){
		try {
			FileOutputStream  fos = this.openFileOutput(filename, Context.MODE_PRIVATE);
			fos.write("试验测试文件".getBytes());
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
1-2,从手机中读取文件

	private void readFile(String filename) {
		try {
			FileInputStream fis = this.openFileInput(filename);
			String content = readInStream(fis);
			Log.i("readFile", content);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String readInStream(FileInputStream inStream) {
		try {
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int length = -1;
			while ((length = inStream.read(buffer)) != -1) {
				// 0-起始位置,length-个数
				// 将buffer数组从下标0开始的length个字节数据写入到内存输出流中
				//下次循环存入时outStream中的字节数组下标增长一个length
				outStream.write(buffer, 0, length);
			}
			outStream.close();
			inStream.close();
			return outStream.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
2-1,写入文件到SDCard

注意:写文件到SDCard需要权限:

	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	private void saveFileToSD(String content, String filename) {
		// 首先判断手机是否安装了SD卡
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			 File SdDir = Environment.getExternalStorageDirectory();
			
			 File file = new File(SdDir, filename);
			 FileOutputStream fos;
			 try {
			 fos = new FileOutputStream(file);
			 fos.write(content.getBytes());
			 fos.close();
			 } catch (Exception e) {
			 Log.i("SaveToSD", "fail");

			 }
		} else {
			Toast.makeText(this, "未安装SD卡", Toast.LENGTH_LONG).show();
		}
	}

二、SharedPreferences 用于对软件配置参数的保存,背后是使用的XML格式保存

1,写入到SharedPreferences数据

	private void saveToSP(String name, String password) {
		// 拿到一个SharedPreferences
		SharedPreferences sp = this.getSharedPreferences("config", Context.MODE_PRIVATE);
		//获取编辑器
		Editor editor = sp.edit();
		editor.putString("name", name);
		editor.putString("password", password);
		//提交修改
		editor.commit();
	}
2-1,从本应用的SharedPreferences中读取数据

	private Map<String,String> readFromSP() {
		// 
		SharedPreferences sp = this.getSharedPreferences("config",Context.MODE_PRIVATE);
		Map<String, String> map = (Map<String, String>) sp.getAll();
		return map;
	}
2-2,从其他应用的SharedPreferences中读取数据

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 写入文件
		// writeFile("filename.txt");
		// 读取文件
		// readFile("filename.txt");
		// 把文件写入SD卡
		// saveFileToSD("save file to sdcard...", "file.txt");
		// 使用preferences保存
		// saveToSP("libing","123456");
		// 从SharedPreferences中读取数据
		Context otherAppContext;
		try {
			//获取其他应用的Context
			otherAppContext = createPackageContext("com.example.sms",
					Context.CONTEXT_IGNORE_SECURITY);
			Map<String, String> data = readFromOtherSP(otherAppContext);
			Log.i("Map", data.toString());
		} catch (NameNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}

	@SuppressLint("WorldReadableFiles")
	private Map<String, String> readFromOtherSP(Context context) {
		@SuppressWarnings("deprecation")
		SharedPreferences sp = context.getSharedPreferences("config",
				Context.MODE_WORLD_READABLE);
		@SuppressWarnings("unchecked")
		Map<String, String> map = (Map<String, String>) sp.getAll();
		return map;
	}

三、SQLite数据库

使用SQLite数据库操作有两种方式:一种是利用execSQL()和rawQuery()执行SQL语句对数据进行操作;此外,SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query() 。

1,利用execSQL()和rawQuery()执行SQL语句

	private String query(SQLiteDatabase db, String name) {
		// TODO 自动生成的方法存根
		Cursor cursor = db.rawQuery("select * from person where name=?",
				new String[] { name });
		Map<Integer,String> map = new HashMap<Integer,String>();
		String data;
		int id,age,i=0;
		String username;
		while (cursor.moveToNext()) {
			id = cursor.getInt(0);
			username = cursor.getString(1);
			age = cursor.getInt(2);
			data = Integer.toString(id) +" "+ username+" "
					+ Integer.toString(age);
			map.put(++i, data);
		}
		cursor.close();
		return map.toString();
	}

	private void update(SQLiteDatabase db, String newValue, String oldValue) {
		// TODO 自动生成的方法存根
		// db.execSQL("update person set name='"+newValue+"'"+
		// " where name='"+oldValue+"'");
		// 改进版
		db.execSQL("update person set name=? where name=?", new Object[] {
				newValue, oldValue });
	}

	private void delete(SQLiteDatabase db, String name) {
		// SQL语句直接拼装
		db.execSQL("delete from person where name='" + name + "'");
		// 使用改进的方式
		db.execSQL("delete from person where name=?", new Object[] { name });
	}

	private void add(SQLiteDatabase db, String name, int age) {
		// 无特殊字符时可以直接用SQL语句来拼装
		// db.execSQL("insert into person(name,age) values("+"'"+name+"'"+","+Integer.toString(age)+")");
		// 有特殊字符时
		db.execSQL("insert into person(name,age) values(?,?)", new Object[] {
				name, age });

	}

2,SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query() 

private String query(SQLiteDatabase db, String table, String name) {
		Cursor cursor = db.query(table, new String[] { "personid", "name",
				"age" }, "name=?", new String[] { name }, null, null,
				"personid desc");
		Map<Integer, String> map = new HashMap<Integer, String>();
		String data;
		int id, age, i = 0;
		String username;
		while (cursor.moveToNext()) {
			id = cursor.getInt(0);
			username = cursor.getString(1);
			age = cursor.getInt(2);
			data = Integer.toString(id) + " " + username + " "
					+ Integer.toString(age);
			map.put(++i, data);
		}
		cursor.close();
		return map.toString();
	}

	private void update(SQLiteDatabase db, String table, String newValue,
			String oldValue) {
		ContentValues values = new ContentValues();
		values.put("name", newValue);
		db.update(table, values, "name=?", new String[] { oldValue });
	}

	private void delete(SQLiteDatabase db, String table, String name) {
		db.delete(table, "name=?", new String[] { name });
	}

	private void add(SQLiteDatabase db, String table, String name, int age) {
		ContentValues values = new ContentValues();
		values.put("name", name);
		values.put("age", age);
		db.insert(table, null, values);
	}

3,使用事务操作SQLite数据库

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		MyOpenHelper openHelper = new MyOpenHelper(this);
		SQLiteDatabase db = openHelper.getWritableDatabase();
		db.beginTransaction();//开启一个事务
		try{
		// 增
		add(db, "person", "libing", 23);
		// 删
		 delete(db,"person","libing");
		// 改
		 update(db,"person","libingbing","libing");
		db.setTransactionSuccessful();//如果执行此语句,则说明修改完成
		// 查
		String data = query(db,"person", "libing");
		Log.i("content of database", data);
		}
		finally{
			db.endTransaction();//如果db.setTranscationSuccessful()执行,则此处提交;否则回滚。
			db.close();
		}
	}

四、ContentProvider内容提供者,对外共享数据

ContentProvider中操作的数据可以来自数据库,也可以是文件、xml或网络等其他存储方式

1,以操作数据库为例

1)首先编写类继承ContentProvider

public class PersonContentProvider extends ContentProvider {
	private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int PERSONS = 1;
	private static final int PERSON = 2;
	private DBOpenHelper dbOpenHelper;
	static {
		matcher.addURI("com.example.contentprovider.personprovider", "person", PERSONS);
		matcher.addURI("com.example.contentprovider.personprovider", "person/#", PERSON);
	}
	//被创建时回调
	@Override
	public boolean onCreate() {
		dbOpenHelper = new DBOpenHelper(this.getContext());
		return true;
	}
	//增
	//参数(Uri uri, ContentValues values)向uri中添加values内容
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		long id = 0;
		switch (matcher.match(uri)) {
		case PERSONS:
			id = db.insert("person", "personid", values);//  insert into person (personid) values(null)
			getContext().getContentResolver().notifyChange(uri, null);
			return ContentUris.withAppendedId(uri, id);// 返回代表新增记录的Uri
		case PERSON:
			id = db.insert("person", "personid", values);
			String strUri = uri.toString();
			Uri personUri = Uri.parse(strUri.substring(0,
					strUri.lastIndexOf("/")));
			getContext().getContentResolver().notifyChange(personUri, null);
			return ContentUris.withAppendedId(personUri, id);
		default:
			throw new IllegalArgumentException("Unkown Uri:" + uri);
		}
	}
	//删
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		int num = 0;// 已经删除的记录数量
		switch (matcher.match(uri)) {
		case PERSONS:
			num = db.delete("person", selection, selectionArgs);
			break;
		case PERSON:
			long id = ContentUris.parseId(uri);
			String where = "personid=" + id;
			if (selection != null && !"".equals(selection)) { 
				where = where + " and " + selection;
			}
			num = db.delete("person", where, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unkown Uri:" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return num;
	}

	//改
	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		int num = 0;// 已经修改的记录数量
		switch (matcher.match(uri)) {
		case PERSONS:
			num = db.update("person", values, selection, selectionArgs);
			break;
		case PERSON:
			long id = ContentUris.parseId(uri);
			String where = "personid=" + id;
			if (selection != null && !"".equals(selection)) {
				where = where + " and " + selection;
			}
			num = db.update("person", values, where, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unkown Uri:" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);// 通知数据发生变化
		return num;
	}

	//查
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		switch (matcher.match(uri)) {
		case PERSONS:
			return db.query("person", projection, selection, selectionArgs,
					null, null, sortOrder);

		case PERSON:
			long id = ContentUris.parseId(uri);
			String where = "personid=" + id;
			if (selection != null && !"".equals(selection)) { 
				where = where + " and " + selection;
			}
			return db.query("person", projection, where, selectionArgs, null,
					null, sortOrder);

		default:
			throw new IllegalArgumentException("Unkown Uri:" + uri);
		}
	}
	@Override
	public String getType(Uri uri) {// 返回当前操作的数据类型
		switch (matcher.match(uri)) {
		case PERSONS:// 操作的是集合类型数据
			return "vnd.android.cursor.dir/person";
		case PERSON:
			return "vnd.android.cursor.item/person";
		default:
			throw new IllegalArgumentException("Unkown Uri:" + uri);
		}
	}


}

2)然后用ContentResolver对ContentProvider数据操作

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ContentResolver resolver = this.getContentResolver();
		// 增加记录
		ContentValues values = new ContentValues();
		values.put("name", "libing");
		values.put("age", 23);

		Uri uri = resolver
				.insert(Uri
						.parse("content://com.example.contentprovider.personprovider/person"),
						values);
		values.clear();
		values.put("name", "libing");
		values.put("age", 34);
		Uri uri1 = resolver
				.insert(Uri
						.parse("content://com.example.contentprovider.personprovider/person"),
						values);
		values.clear();
		Log.i("Uri-add", Long.toString(ContentUris.parseId(uri1)));
		// 删除记录
//		resolver.delete(
//				Uri.parse("content://com.example.contentprovider.personprovider/person"),
//				"name=? and age=?", new String[] { "libing", "23" });
		// 修改记录
		values.put("name", "minmin");
		values.put("age", 23);
		resolver.update(
				Uri.parse("content://com.example.contentprovider.personprovider/person"),
				values, "age=34", null);
		//查询记录
		Cursor cursor = resolver.query(Uri.parse("content://com.example.contentprovider.personprovider/person"), 
				null, "name=? or name=?", new String[]{"minmin","libing"}, "personid");
		while(cursor.moveToNext()){
			Log.i("CURSOR", cursor.getInt(0)+" "+cursor.getString(1)+" "+cursor.getInt(2));
			
		}
		cursor.close();
	}

五、从网络获取数据

1,使用Socket进行通信

1)服务器端的程序,一般以PC机作为服务器端,因为手机的IP地址是由运营商动态分配,而PC的IP一般固定。

	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		
		ServerSocket ss = new ServerSocket(30000);
		while(true){
			Socket socket = ss.accept();
			OutputStream os = socket.getOutputStream();
			os.write("服务器已经接受您的请求。。。".getBytes("utf-8"));
			os.close();
			socket.close();
			
		}
		
	}

2)客户端的程序:

网络连接属于耗费时间的操作,故应该开启新的线程来完成,避免阻塞主线程。

		new Thread(){
			public void run(){
				try{
					Socket socket = new Socket("172.24.36.95", 30000);
					//获得输入流,输入流是字节流信息,故需要转化成字符流
					//而InputStreamReader正是字节流到字符流的桥梁,它能将字节流解码为字符流
					//为了提高转换效率,用BufferdReader对其进行包装
					BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
					StringBuilder sb = new StringBuilder();
					String line;
					while((line=br.readLine())!=null){
						sb.append(line);
					}
					Log.i("information from server", sb.toString());
					br.close();
					socket.close();
					
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}.start();


2,使用URL访问网络资源

1)使用URL

	ImageView imageView;
	Bitmap bitmap;

	Handler myHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.what == 0x110) {
				imageView.setImageBitmap(bitmap);
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

//		socketLink("172.24.36.95", 30000);

		imageView = (ImageView) this.findViewById(R.id.iv_1);
		try {
			urlLink(new URL(
					"http://p3.wmpic.me/article/2015/02/10/1423552790_HGrFkNfN.jpg"));
		} catch (MalformedURLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}

2)使用URLConnection

待整理。。

3,使用HTTP访问网络

待整理。。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值