王君涵 發表於 2021-9-2 18:19:00

Android开发——数据存储

<p>先编写一个简单的QQ登录界面作为实验界面</p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"<span style="color: rgba(0, 0, 0, 1)">
    android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
    android:layout_height</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
    android:background</span>="@mipmap/qq_login"&gt;

    &lt;<span style="color: rgba(0, 0, 0, 1)">LinearLayout
      android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_marginTop</span>="50dp"<span style="color: rgba(0, 0, 0, 1)">
      android:orientation</span>="vertical"<span style="color: rgba(0, 0, 0, 1)">
      android:padding</span>="30dp"&gt;

      &lt;<span style="color: rgba(0, 0, 0, 1)">TextView
            android:layout_width</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
            android:drawableLeft</span>="@mipmap/ic_launcher"<span style="color: rgba(0, 0, 0, 1)">
            android:text</span>="QQ"<span style="color: rgba(0, 0, 0, 1)">
            android:textColor</span>="#888888"<span style="color: rgba(0, 0, 0, 1)">
            android:textSize</span>="50sp"/&gt;

      &lt;<span style="color: rgba(0, 0, 0, 1)">EditText
            android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_height</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_marginTop</span>="30dp"<span style="color: rgba(0, 0, 0, 1)">
            android:hint</span>="QQ号码\手机号码\邮箱"<span style="color: rgba(0, 0, 0, 1)">
            android:textColorHint</span>="#888888"/&gt;

      &lt;<span style="color: rgba(0, 0, 0, 1)">EditText
            android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_height</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:hint</span>="密码"<span style="color: rgba(0, 0, 0, 1)">
            android:textColorHint</span>="#888888"/&gt;

      &lt;<span style="color: rgba(0, 0, 0, 1)">Button
            android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
            android:text</span>="登录"<span style="color: rgba(0, 0, 0, 1)">
            android:textSize</span>="20sp"/&gt;

      &lt;<span style="color: rgba(0, 0, 0, 1)">RelativeLayout
            android:layout_width</span>="match_parent"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
            android:layout_marginTop</span>="10dp"
            &gt;

            &lt;<span style="color: rgba(0, 0, 0, 1)">TextView
                android:layout_width</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
                android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
                android:text</span>="忘记密码"<span style="color: rgba(0, 0, 0, 1)">
                android:textColor</span>="#00aaff"<span style="color: rgba(0, 0, 0, 1)">
                android:textSize</span>="16sp"/&gt;

            &lt;<span style="color: rgba(0, 0, 0, 1)">TextView
                android:layout_width</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
                android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
                android:text</span>="新用户注册"<span style="color: rgba(0, 0, 0, 1)">
                android:textColor</span>="#00aaff"<span style="color: rgba(0, 0, 0, 1)">
                android:textSize</span>="16sp"<span style="color: rgba(0, 0, 0, 1)">
                android:layout_alignParentRight</span>="true"/&gt;

      &lt;/RelativeLayout&gt;

    &lt;/LinearLayout&gt;

    &lt;<span style="color: rgba(0, 0, 0, 1)">TextView
      android:layout_width</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_height</span>="wrap_content"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_alignParentBottom</span>="true"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_centerHorizontal</span>="true"<span style="color: rgba(0, 0, 0, 1)">
      android:text</span>="登录即代表阅读并同意相关条款"<span style="color: rgba(0, 0, 0, 1)">
      android:layout_marginBottom</span>="50dp"<span style="color: rgba(0, 0, 0, 1)">
      android:textColor</span>="#777777"<span style="color: rgba(0, 0, 0, 1)">
      android:textSize</span>="20sp"/&gt;

&lt;/RelativeLayout&gt;</span></pre>
</div>
<p>效果如下</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902101929853-97774046.png"></p>
<p>&nbsp;</p>
<h1>&lt;1&gt;把数据存储到该应用的数据目录(\data)中</h1>
<p>首先对登录按钮、账号输入框、密码输入框这三个控件设置id</p>
<p>然后对登录按键设置监听事件(点击登录按钮,就会触发监听事件,将账号框和密码框中的内容存储起来)</p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> handlerLoginEvent(View v){
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">点击登录按钮后,要拿到界面上的内容(账号和密码)</span>
      String accountText =<span style="color: rgba(0, 0, 0, 1)"> account.getText().toString();
      String passwordText </span>=<span style="color: rgba(0, 0, 0, 1)"> password.getText().toString();

      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把账户和密码保存起来
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">利用流把它们写到文件中保存起来</span>
<span style="color: rgba(0, 0, 0, 1)">      saveUserInfo(accountText,passwordText);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> saveUserInfo(String a,String p){
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把账号和密码存储起来的方法</span>
      Log.d(TAG,"保存用户的账号和密码..."<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(255, 0, 0, 1)">            File file </span></span><span style="color: rgba(255, 0, 0, 1)">= new File("/data/data/com.example.qq_logindemo/zhanghu.txt");</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">file.exists()){
                file.createNewFile();
            }
            FileOutputStream fos </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileOutputStream(file);
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">以特定的格式来存储:账号***密码</span>
            fos.write((a +"***" +<span style="color: rgba(0, 0, 0, 1)"> p).getBytes());
            fos.close();
      } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
            e.printStackTrace();
      }
    }</span></span></pre>
</div>
<p>——这里需要注意的是,文件保存的路径如何确定?</p>
<p>如果我们直接写File file=new File("zhanghu.txt")是会出错的,因为Android系统是基于Linux系统的,不像windows系统一样有C盘D盘之类的盘进行区分,它的根目录就是"/"</p>
<p>而每一个Android程序就是一个用户,在linux下权限的划分非常清楚,每一个用户只能操作自己的数据,具有安全性</p>
<p>所以我们必须将账号和密码的信息保存到我们的这个qq_logindemo应用的数据目录中才可以</p>
<p>&nbsp;</p>
<p>——如何找到具体路径呢?</p>
<p>打开cmd,输入adb devices查看我们的虚拟设备</p>
<p>输入adb shell进入该设备的Android内核</p>
<p>输入ll查看目录可以看到有一个data文件夹</p>
<p>进入data文件夹中,可以看到还有一个data文件夹,再次进入(即cd data,再次cd data)</p>
<p>在/data/data目录下我们再次ll查看目录,就可以看到我们应用程序的数据文件地址了</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902111725834-1104277080.png"></p>
<p>com.example.qq_logindemo就是我们的应用程序数据地址(也可以在AS中我们的项目中manifests下的AndroidManifest.xml中找到验证)</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902112021285-318629824.png"></p>
<p>当我们在手机上输入账号和密码,按下登录按键后,就会在该程序的目录下创建了一个zhanghu.txt文本按照"账号***密码"的格式存储我们的数据,验证一下:</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902112547449-1680857855.png"></p>
<p>&nbsp;</p>
<h1>&lt;2&gt;查看保存的数据</h1>
<p>——第一种方式:在Android系统内核中用linux命令 cat zhanghu.txt 查看文本文件的内容</p>
<p>&nbsp;</p>
<p>——第二种方式:在AS中,上方菜单栏View中选择Tool Windows中的Devices File Explorer即可</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902114307312-843185235.png"></p>
<p>然后即可在AS中查看到该设备的所有文件,找到/data/data/com.example.qq_logindemo/zhanghu.txt打开即可看到</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902114450619-830609871.png"></p>
<p>&nbsp;</p>
<h1>&lt;3&gt;获取文件保存路径的另一种方法——利用系统自带的API</h1>
<p>在第一个模块中, 我们选择了通过adb命令进入Android内核,然后再用Linux系统的相应操作找到文件存储的位置</p>
<p>其实还有一种更便捷的方式,直接在代码里用系统自带的API即可</p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> saveUserInfo(String a,String p){
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把账号和密码存储起来的方法</span>
      Log.d(TAG,"保存用户的账号和密码..."<span style="color: rgba(0, 0, 0, 1)">);

      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">利用API获取文件保存的路径</span>
      <span style="color: rgba(255, 0, 0, 1)">File filesDir = this.getFilesDir();
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">输出文件保存的路径</span>
      Log.d(TAG,"files dir == " +<span style="color: rgba(0, 0, 0, 1)"> filesDir.toString());
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">利用API获取的路径来自动在下面创建一个文本,保存账号和密码</span>
       <span style="color: rgba(255, 0, 0, 1)"> File saveFile = new File(filesDir,"zhanghu.txt");

      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
            </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
            File file = new File("/data/data/com.example.qq_logindemo/zhanghu.txt");
            if(!file.exists()){
                file.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(file);
             </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">saveFile.exists()){
                <span style="color: rgba(255, 0, 0, 1)">saveFile.createNewFile();</span>
            }
            FileOutputStream fos </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileOutputStream(<span style="color: rgba(255, 0, 0, 1)">saveFile</span>);
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">以特定的格式来存储:账号***密码</span>
            fos.write((a +"***" +<span style="color: rgba(0, 0, 0, 1)"> p).getBytes());
            fos.close();
      } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
            e.printStackTrace();
      }
    }</span></span></pre>
</div>
<p>(即 this.getFileDir() 方法拿到的路径就是 /data/data/包名/files 这个路径)</p>
<p>(同理,获取缓存文件存储的路径也是有相应的方法 this.getCacheDir() )</p>
<p>缓存文件,保存在cache目录中,会由系统根据存储情况自动进行清理</p>
<p>而files目录下是我们自己保存文件的地址,可以通过代码删除,也可以通过手机里的应用列表中的选项进行删除数据</p>
<p>&nbsp;</p>
<h1>&lt;4&gt;对输入的数据进行判空</h1>
<p>在设计qq登录界面时,需要对输入的账号密码进行各种检查</p>
<p>(在实际开发中,各种合法性检查一般交给后台处理)</p>
<p>这里对账号和密码的判空处理进行练习,两种方法</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902135628351-1905312293.png"></p>
<p>&nbsp;</p>
<h1>&lt;5&gt;把存储的账号和密码从文件中读取出来,回显到界面上</h1>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902141744039-1335721231.png"></p>
<p>&nbsp;</p>
<h1>&lt;6&gt;把数据存储到SD卡中</h1>
<p>在Android设备中,其实是有两种存储空间:</p>
<p>——一是系统内部存储空间:ROM,就类似于Windows系统的C盘,在Android系统中只有一个ROM盘,因为它是基于Linux系统的</p>
<p>——二是外置存储空间:也就是SD卡等外部存储设备,类似于Windows系统的外插存储设备</p>
<p>&nbsp;</p>
<p>首先,外部存储设备在Linux系统中是需要挂载的</p>
<p>adb devices,然后adb shell 进入Android内核,然后 cd /mnt 即可进入挂载的目录</p>
<p>ll查看sd卡所挂载的路径</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902143853165-807188448.png"></p>
<p>&nbsp;</p>
<p>然后写代码,设置一个点击按键,点击后往SD卡中存储数据</p>
<p>需要注意的是,往SD卡中存储和读取数据也是要获取权限的</p>
<p>我们要在AndroidManifest.xml中配置一下,加入读写权限</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902152146611-1554662221.png"></p>
<p>然后在界面点击按键,去挂载SD卡的路径中就可以看到新建的一个文件了</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902152334203-537242466.png"></p>
<p>&nbsp;</p>
<h1>&lt;7&gt;使用API获取SD卡路径以及判断SD卡是否挂载以及查看SD卡剩余存储空间大小</h1>
<p>和前面的获取数据的内部存储路径一样,SD卡的路径也可以通过调用API来实现</p>
<p>File exFile = Environment.getExternalStorageDirectory();</p>
<p>这种方法的好处是什么呢?</p>
<p>一是避免写错,二是因为不同的手机厂商,它们默认的SD卡路径名不一样,通过这个API,可以便捷得获取到SD卡的路径</p>
<p>&nbsp;</p>
<p>如何判断是否挂载了SD卡?</p>
<p>也可以通过一个API</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902160052709-1089385224.png"></p>
<p>&nbsp;</p>
<p>如何查看SD卡剩余的存储空间大小?</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902161805475-1033569283.png"></p>
<p>&nbsp;</p>
<h1>&lt;8&gt;编写设置界面SharedPreference</h1>
<p>SharedPreference一般用于保存偏好设置,例如手机设置界面里的各个选项</p>
<p>(在Android系统中,分为内部存储和外部存储,而内部存储又分为以下几种路径:</p>
<p>——/data/data/包名/files:存储文件</p>
<p>——/data/data/包名/caches:存储缓存</p>
<p>——/data/data/包名/databases:存储数据库</p>
<p>——/data/data/包名/shared_prefs:存储设置,也就是用户偏好)</p>
<p>&nbsp;</p>
<p>SharedPreference的使用步骤:</p>
<p>1.首先拿到这个SharedPreference</p>
<p>用this.getSharedPreference()方法,里面的两个参数第一个是表示存储的文件名称,第二个表示权限</p>
<p>2.进入编辑模式,拿到编辑器</p>
<p>3.保存数据</p>
<p>edit.putBoolean("键名称", 值);</p>
<p>可以保存的类型有String,float,StringSet,int</p>
<p>4.提交编辑器</p>
<p>edit.commit();</p>
<p>通过这四步,我们即可将数据保存在SharedPreference里了</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902180453193-32529211.png"></p>
<p>&nbsp;</p>
<p>SharedPreference中的数据回显?</p>
<p><img src="https://img2020.cnblogs.com/blog/2505674/202109/2505674-20210902181419553-1697833844.png"></p>
<p>&nbsp;</p>
<p>SharedPreference存储的数据都是键值对</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/danile97/p/15220056.html
頁: [1]
查看完整版本: Android开发——数据存储