zoukankan      html  css  js  c++  java
  • Android数据存储系列————SharedPreferences

    目录

    前言

    要点代码

    示例代码

    commit()和apply()的异同点

    前言

      介绍:SharedPreferences是一个轻量型的数据存储,一般用于存储用户的用户信息如账号,密码,是Android自带的一个本地存储。

      主要作用:实现记住密码和自动登录功能

      存储形式:以xml文件形式存储

      存储位置:/data/data/包名/shared_prefs文件下【这个可以根据File Explorer查看,这里不做说明】

      操作流程:

    • 创建SharedPreferences对象
    • 保存数据

    要点:SharedPreferences只支持Java的基本数据类型

    要点代码:

    1、创建SharedPreferences对象

    private SharedPreferences sharedPreferences;
    /**
     * 参数1:文件信息存放文件
     * 参数2:操作模式MODE_PRIVATE:私有模式,新内容覆盖原内容
    */
    sharedPreferences=getSharedPreferences("userInfo",MODE_PRIVATE);

     操作模式介绍:

    • MODE_PRIVATE:默认模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
    • MODE_WORLD_READABLE:允许其他应用读取这个模式创建的文件。在Android N上使用该模式将抛出SecurityException异常。【这个弃用了,不要问怎么知道了,知道的时候已经是泪了】
    • MODE_WORLD_WRITEABLE:允许其他应用写入这个模式创建的文件。在Android N上使用该模式将抛出SecurityException异常。【这个弃用了,不要问怎么知道了,知道的时候已经是泪了】
    • MODE_APPEND:如果文件已经存在了,则在文件的尾部添加数据。【这个没用过】
    • MODE_MULTI_PROCESS:SharedPreferences加载标志,当设置了该标志,则在磁盘上的文件将会被检查是否修改了,尽管SharedPreferences实例已经在该进程中被加载了。【这个没用过,看其他博主推荐使用ContentProvider】

     2、保存数据

    第一步:创建一个SharedPreferences.Editor类的对象

    SharedPreferences.Editor editor = sharedPreferences.edit();

    第二步:通过SharedPreferences.Editor类的对象修改数据,不同的数据类型有不同的修改数据方法如,putString,putInt,putLong等方法,所有的方法都是一个参数是键的名称,第二个参数是键的值

    editor.putBoolean("ISCHECK", true);

    第三步:数据输入好后需要提交才能保存数据,调用方法commit()或者apply();【两者的区别

    //方法一
    editor.commit();
    //方法二
    editor.apply();

    示例代码:

    登录成功提示页布局代码【login.xml]

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:text="登录成功"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    用户登录布局代码【main.xml】

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:text="账号:"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <EditText
            android:id="@+id/edit_account"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="密码:"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <EditText
            android:id="@+id/edit_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <CheckBox
                android:text="记住密码"
                android:id="@+id/checkbox_rememberpass"
                android:layout_width="match_parent"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
            <CheckBox
                android:text="自动登录"
                android:id="@+id/checkbox_againlogin"
                android:layout_width="match_parent"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
            <Button
                android:text="登录"
                android:id="@+id/button_login"
                android:layout_width="match_parent"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </LinearLayout>

    登录成功提示页Java代码【Login.java】

    package com.hacker.exercise_sharedperference;
    
    import android.os.Bundle;
    
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    
    public class Login extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.login);
        }
    }

    用户登录Java代码【MainActivity.java】

    package com.hacker.exercise_sharedperference;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.EditText;
    import android.widget.Toast;
    
    /**
     * 目的:初步学习SharedPreferences
     * 结果:实现自动登录和记住密码
     */
    public class MainActivity extends AppCompatActivity {
        //账号,密码
        private EditText account,password;
        //记住密码和自动登录
        private CheckBox rempass,agalogin;
        //登录
        private Button button;
        //用户名文本,密码文本
        private String userNameValue,passwordValue;
        //sharedPreferences,轻量型存储
        private SharedPreferences sharedPreferences;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            /**
             * 参数1:文件信息存放文件
             * 参数2:操作模式MODE_PRIVATE:私有模式,新内容覆盖原内容
             */
            sharedPreferences=getSharedPreferences("userInfo",MODE_PRIVATE);
            account=findViewById(R.id.edit_account);
            password=findViewById(R.id.edit_password);
            rempass=findViewById(R.id.checkbox_rememberpass);
            agalogin=findViewById(R.id.checkbox_againlogin);
            button=findViewById(R.id.button_login);
    
            //判断记住密码多选框的状态
            if(sharedPreferences.getBoolean("ISCHECK", false))
            {
                //设置默认是记录密码状态
                rempass.setChecked(true);
                account.setText(sharedPreferences.getString("USER_NAME", ""));
                password.setText(sharedPreferences.getString("PASSWORD", ""));
                //判断自动登陆多选框状态
                if(sharedPreferences.getBoolean("AUTO_ISCHECK", false))
                {
                    //设置默认是自动登录状态
                    agalogin.setChecked(true);
                    //跳转界面
                    Intent intent = new Intent(MainActivity.this,Login.class);
                    MainActivity.this.startActivity(intent);
    
                }
            }
    
            // 登录监听事件  现在默认为用户名为:lin 密码:123
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.i("步骤2","1");
                    userNameValue = account.getText().toString();
                    passwordValue = password.getText().toString();
    
                    if(userNameValue.equals("lin")&&passwordValue.equals("123"))
                    {
                        Toast.makeText(MainActivity.this,"登录成功", Toast.LENGTH_SHORT).show();
                        //登录成功和记住密码框为选中状态才保存用户信息,即rempass.isChecked()为true时候进入if语句
                        if(rempass.isChecked())
                        {
                            //记住用户名、密码、
                            SharedPreferences.Editor editor = sharedPreferences.edit();
                            editor.putString("USER_NAME", userNameValue);
                            editor.putString("PASSWORD",passwordValue);
                            editor.apply();
                        }
                        //跳转界面
                        Intent intent = new Intent(MainActivity.this,Login.class);
                        MainActivity.this.startActivity(intent);
                    }else{
                        Toast.makeText(MainActivity.this,"用户名或密码错误,请重新登录", Toast.LENGTH_LONG).show();
                    }
                }
            });
    
            //监听记住密码多选框按钮事件
            rempass.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (rempass.isChecked()) {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putBoolean("ISCHECK", true);
                        editor.apply();
    
                    }else {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putBoolean("ISCHECK", false);
                        editor.apply();
                    }
                }
            });
            agalogin.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (agalogin.isChecked()) {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putBoolean("AUTO_ISCHECK", true);
                        editor.apply();
                    } else {
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putBoolean("AUTO_ISCHECK", false);
                        editor.apply();
                    }
                }
            });
        }
        /**
         * 未优化时候,提示Skipped 33 frames!  The application may be doing too much work on its main thread.
         */
    }

    commit()和apply()的异同点:

    commit()

            /**
             * Commit your preferences changes back from this Editor to the
             * {@link SharedPreferences} object it is editing.  This atomically
             * performs the requested modifications, replacing whatever is currently
             * in the SharedPreferences.
             *
             * <p>Note that when two editors are modifying preferences at the same
             * time, the last one to call commit wins.
             *
             * <p>If you don't care about the return value and you're
             * using this from your application's main thread, consider
             * using {@link #apply} instead.
             *
             * @return Returns true if the new values were successfully written
             * to persistent storage.
             */

    apply()

    /**
             * Commit your preferences changes back from this Editor to the
             * {@link SharedPreferences} object it is editing.  This atomically
             * performs the requested modifications, replacing whatever is currently
             * in the SharedPreferences.
             *
             * <p>Note that when two editors are modifying preferences at the same
             * time, the last one to call apply wins.
             *
             * <p>Unlike {@link #commit}, which writes its preferences out
             * to persistent storage synchronously, {@link #apply}
             * commits its changes to the in-memory
             * {@link SharedPreferences} immediately but starts an
             * asynchronous commit to disk and you won't be notified of
             * any failures.  If another editor on this
             * {@link SharedPreferences} does a regular {@link #commit}
             * while a {@link #apply} is still outstanding, the
             * {@link #commit} will block until all async commits are
             * completed as well as the commit itself.
             *
             * <p>As {@link SharedPreferences} instances are singletons within
             * a process, it's safe to replace any instance of {@link #commit} with
             * {@link #apply} if you were already ignoring the return value.
             *
             * <p>You don't need to worry about Android component
             * lifecycles and their interaction with <code>apply()</code>
             * writing to disk.  The framework makes sure in-flight disk
             * writes from <code>apply()</code> complete before switching
             * states.
             *
             * <p class='note'>The SharedPreferences.Editor interface
             * isn't expected to be implemented directly.  However, if you
             * previously did implement it and are now getting errors
             * about missing <code>apply()</code>, you can simply call
             * {@link #commit} from <code>apply()</code>.
             */

    这上面的注释是SDK自带的对这两种的方法解释,总结一下

    相同点

    1、2个编辑器如果同时调用commit()方法或者apply()方法,那么最后一个调用这个方法的输入框(编辑器)将会获得值

    2、2个方法都是一系列操作不可以被打断的方法,即原子操作

    不同点

    1、apply没有返回值,所以也就不知道是否提交成功;而commit方法会返回boolean表明修改是否提交成功

    2、apply是将修改数据原子提交到内存,而后异步真正提交到硬件磁盘;而commit是同步的提交到硬件磁盘,

    3、apply方法调用的情况实在状态切换的时候

    Android建议

    如果不需要返回值,且在主线程中调用,推荐使用apply方法。

  • 相关阅读:
    《VR入门系列教程》之21---使用Unity开发GearVR应用
    《VR入门系列教程》之20---使用Oculus移动端SDK
    《VR入门系列教程》之19---GearVR开发初识
    《VR入门系列教程》之18---Oculus代码剖析
    《VR入门系列教程》之17---发布第一个应用
    《VR入门系列教程》之16---第一个OculusVR应用
    阿里巴巴开发手册提取信息
    国富论
    富通天下(W 笔试)
    富通天下(T 面试)
  • 原文地址:https://www.cnblogs.com/hahayixiao/p/13907898.html
Copyright © 2011-2022 走看看