一、Shared Preferences存储
1、什么是Shared Preferences存储?
它是Android提供的,用来以最简单的方式对数据进行永久保存的方法。
2、使用SharedPreferences存储数据的步骤
① 获取SharedPreferences对象:
方法一:通过getSharedPreferences(String name,int mode),关于参数,第一个name是SharedPreferences文件名,第二个通过Android确认的常量指定访问权限,一般使用MODE_PRIVATE(表示被本应用读写)或MODE_MULTI_PROCESS(可以跨应用读写)指定。
方法二:getPreferences(int mode),只有一个参数,指定访问权限,和上述相同。
② 获取SharedPreferences.Editor对象:
通过调用SharedPreferences的edit()方法实现。
③ 向SharedPreferences.Editor对象中添加数据:
使用Editor对象提供的一些方法保存数据,通过put+数据类型表示的方法(putInt(),putBoolean()等等)。
④ 提交数据:
通过Editor的commit()方法提交。
3、使用SharedPreferences读取数据的步骤
① 获取SharedPreferences对象,如上。
② 使用SharedPreferences类提供的getXxx()方法获取数据(getInt(),getBoolean()等等)
实例:输入账号密码自动登录并存储,下次自动登录
package com.example.sharedpreferences; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private String mr = "mr",mrsoft = "mrsoft";//定义后台账号密码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取布局文件中的组件 final EditText usernameET = findViewById(R.id.username); final EditText passwordET = findViewById(R.id.password); Button button = findViewById(R.id.login); final SharedPreferences sp = getSharedPreferences("mrsoft",MODE_PRIVATE);//获取对象 //实现自动登录功能 String username = sp.getString("username",null);//获取账号信息 String password = sp.getString("password",null); if(username!=null&&password!=null){ if(username.equals(mr)&&password.equals(mrsoft)){//登陆成功跳转 Intent intent = new Intent(MainActivity.this,MessageActivity.class); startActivity(intent); } }else{ //实现手动登录并储存账号密码 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String in_username = usernameET.getText().toString();//获取输入的账号 String in_password = passwordET.getText().toString(); SharedPreferences.Editor editor = sp.edit();//获取editor对象 if(in_username.equals(mr)&&in_password.equals(mrsoft)){ editor.putString("username",in_username);//保存账号 editor.putString("password",in_password); editor.commit();//提交信息 Intent intent = new Intent(MainActivity.this,MessageActivity.class); startActivity(intent); Toast.makeText(MainActivity.this,"已保存账号密码",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this,"账号密码错误",Toast.LENGTH_SHORT).show(); } } }); } } }
二、内部存储
1、文件存储
提供Java的IO流来读取磁盘上的文件,获取输入流的方法openFileInput(),获取输出流openFileOutput()。
2、文件的存储方式
首先内部存储与外部存储都是存储在手机内部的,这与是否插入sd卡没有关系。
内部存储特点:
① 默认只能被创建它的应用访问到。
② 当这个应用卸载后,内部存储的文件也被删除。
③ 一旦内部存储空间耗尽,手机也就无法使用。
实例:设计备忘录保存并读取信息
package com.example.instorage; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class MainActivity extends AppCompatActivity { byte[] buffer = null;//声明字节数组 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText editText = findViewById(R.id.editText); Button btn_save = findViewById(R.id.save); Button btn_cancel = findViewById(R.id.cancel); btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //保存填写的备忘信息 FileOutputStream fos = null; String text = editText.getText().toString();//获取输入的备忘信息 try { fos = openFileOutput("memo",MODE_PRIVATE);//第一次参数文件名,第二个为权限 fos.write(text.getBytes());//写入备忘信息 fos.flush();//清除缓存 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(fos!=null) { try { fos.close();//关闭输出流 Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } } } } }); //读取保存的备忘信息 FileInputStream fis = null; try { fis = openFileInput("memo"); buffer = new byte[fis.available()];//实例化字节数组 fis.read(buffer);//从输入流中读取数据 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(fis!=null) { try { fis.close(); String data = new String(buffer);//把字节数组中的数据转换成字符串 editText.setText(data);//显示读取的内容 } catch (IOException e) { e.printStackTrace(); } } } btn_cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
三、外部存储
不是指存储在手机外面的部分,有一个简单的方法可以区分,电脑手机连接,可以被电脑读取出来的就是外部存储的内容。
读写外部存储空间上文件的步骤:
通过En*nment.getExternalStorageDirectory()获取外部存储目录,使用FileInputStream,FileOutputStream读写文件。
注意,还要再AndroidManifest.xml中声明外部存储的读写权限,代码如下:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
四、数据库SQLite
特点:占用资源少,运行效率高,可移植性强,安全可靠。
操作sqlite数据库的方法:sdk中自带的sqlite3.exe工具或通过Java代码。
1、使用sqlite3.exe
① 首先找到sdk下的paltform-tools目录,并在命令行模式下打开,然后运行其中的adb.exe,利用命令 adb shell ,注意:使用该命令要提前打开虚拟机。然后输入sqlite3命令。如下图
注意:需要是管理员权限。符号为 “#”,若不是,输入命令“su”切换,例如:
即可进入sqlite的交互模式,若要退出,输入命令 .exit(注意前面有点 “ . ” ) 即可退出。
也可直接打开paltform-tools目录下的sqlite3.exe文件也可达到相同目的。
② 我们需要在shell模式下创建数据库文件夹,在data/data/com.(此处为项目包名)/(此处为数据库名),例如:
然后进入该数据库文件夹中,利用命令cd 然后上面的路径名,例如:
进入数据库后会默认使用sqlite交互模式,创建数据库,例如:
然后创建数据表,使用命令create table 表名(字段值),sql语句,例如创建tb_user表,id为整型主键,自动索引,name为文本属性不为空,pwd文本如下:
使用.tables命令查看都有哪些表。
使用insert命令插入数据,使用select命令查看命中数据,与常用sql语句一致,操作结果如下
总结:
2、使用Java代码操作数据库sqlite
首先,SQLite的数据类型:
步骤:
首先,创建数据库,利用方法SQLliteDatabase类的openOnCreateDatabase()创建或打开一个库,或编写继承SQLiteOpenHelper的类来实现。
编写继承SQLiteOpenHelper的类DatabaseHelper,利用onCreate()方法创建表,此方法是在数据库第一次调用时使用,一般用于创建数据库表和初始化数据库,然后通过execSQL()方法执行SQL语句。
其次,操作数据库。四种基本操作,增insert(),删delete(),改update(),查query()。
3、Cursor
Cursor是结果集游标,与JDBC中的ResultSet作用相似,使用moveToNext()方法将游标从当前移动到下一行。
实例,词典(见下篇博客)
五、ContentProvider
ContentProvider可以实现在不同程序间数据共享的功能,同时保证安全性。关于ContentProvider,很重要的两点是数据模型和URI。
1、数据模型
ContentProvider使用基于数据模型的简单表格来提供其中的数据。
2、URI
容易和URL混淆。URL,格式:http://www.name.com/news.php ,其中:
http://代表URL协议,这是固定的。中间代表网站的域名,最后是网站的资源,动态。
URI,格式:content://com.xxx.xxx 其中:
content://是Android固定的格式,代表由ContentProvider统一管理。中间是URI的权限部分,用来对不同的应用程序加以区分。最后是ContentProvider的路径,表示数据等。
区别:
URI是统一资源标识符,比较笼统的定义资源,不区分客户端服务器。
URL是统一资源定位符,定位网上一切资源。
3、创建和使用ContentProvider的步骤
首先,继承ContentProvider类,用来创建一个新的数据提供者。
然后,声明ContentProvider。在AndroidManifest.xml中提供<provider>标记进行声明。
之后便是使用ContentProvider,增删改查四种操作。使用的是ContentResolver类下的insert(),delete(),update(),query()。
实例:读取手机联系人(见下篇博客)