Stockage et accès aux données - SharedPreferences enregistre les paramètres de préférence de l'utilisateur


Introduction à cette section :

Cette section vous présente la deuxième façon de stocker les données utilisateur, en utilisant SharedPreferences (enregistrer les paramètres de préférence utilisateur) pour enregistrer les données. Lorsque notre application souhaite enregistrer certains paramètres de préférence de l'utilisateur, comme s'il faut se connecter automatiquement, s'il faut mémoriser le mot de passe du compte et s'il faut utiliser le Wifi. Pour le réseautage et autres informations connexes, si vous utilisez une base de données, cela semble un peu exagéré ! Nous appelons les informations de configuration ci-dessus préférences utilisateur Les paramètres sont les paramètres des préférences de l'utilisateur, et ces informations de configuration sont généralement enregistrées dans des fichiers spécifiques ! Par exemple, Windows utilise des fichiers ini, Dans J2SE, les fichiers de propriétés et les fichiers XML sont utilisés pour enregistrer les informations de configuration du logiciel sous Android que nous utilisons habituellement ; Une classe de stockage légère - SharedPreferences pour enregistrer les paramètres de préférences utilisateur ! SharedPreferences utilise également des fichiers XML, Ensuite, comme pour la collection Map, les données sont stockées sous forme de clé-valeur ; il suffit d'appeler getXxx(name) de SharedPreferences, Vous pouvez obtenir la valeur correspondante en fonction de la clé ! C'est si simple à utiliser !


1. Exemple d'utilisation de SharedPreferences :

Utiliser un organigramme :

1.png

Exemple de code d'implémentation :

Diagramme des effets d'exécution :

Le processus consiste à saisir le mot de passe du compte, à cliquer sur Connexion, puis à enregistrer les informations dans SharedPreference. déposer. Ensuite, redémarrez l'application et voyez que les données ont été affichées dans la zone de texte

2.gif

Après l'enregistrement, nous pouvons ouvrir data/data/<Package Name> Voir dans le répertoire shared_prefs Un fichier xml a été généré (car le N5 n'a pas de root, voici les rendus précédents) :

3.jpg

Cliquez sur exporter vers le bureau pour voir le contenu à l'intérieur :

4.jpg

Implémentation du code :

Écriture du fichier de mise en page activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MyActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户登陆" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="请输入用户名" />

    <EditText
        android:id="@+id/editname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="用户名" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入密码" />

    <EditText
        android:id="@+id/editpasswd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/btnlogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录" />
</LinearLayout>

Écriture de SP simple classe d'outils : SharedHelper.java :

/**
 * Created by Jay on 2015/9/2 0002.
 */
public class SharedHelper {

    private Context mContext;

    public SharedHelper() {
    }

    public SharedHelper(Context mContext) {
        this.mContext = mContext;
    }


    //定义一个保存数据的方法
    public void save(String username, String passwd) {
        SharedPreferences sp = mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString("username", username);
        editor.putString("passwd", passwd);
        editor.commit();
        Toast.makeText(mContext, "信息已写入SharedPreference中", Toast.LENGTH_SHORT).show();
    }

    //定义一个读取SP文件的方法
    public Map<String, String> read() {
        Map<String, String> data = new HashMap<String, String>();
        SharedPreferences sp = mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
        data.put("username", sp.getString("username", ""));
        data.put("passwd", sp.getString("passwd", ""));
        return data;
    }
}

Enfin, MainActivity.java implémente la logique associée :

public class MainActivity extends AppCompatActivity {

    private EditText editname;
    private EditText editpasswd;
    private Button btnlogin;
    private String strname;
    private String strpasswd;
    private SharedHelper sh;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();
        sh = new SharedHelper(mContext);
        bindViews();
    }

    private void bindViews() {
        editname = (EditText)findViewById(R.id.editname);
        editpasswd = (EditText)findViewById(R.id.editpasswd);
        btnlogin = (Button)findViewById(R.id.btnlogin);
        btnlogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                strname = editname.getText().toString();
                strpasswd = editpasswd.getText().toString();
                sh.save(strname,strpasswd);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Map<String,String> data = sh.read();
        editname.setText(data.get("username"));
        editpasswd.setText(data.get("passwd"));
    }
}

2. Lire les préférences partagées

Core des autres applications : Obtenez le contexte d'autres applications, et ce contexte représente l'interface d'accès aux informations globales de l'application et détermine l'identification unique de l'application. Il s'agit du nom du package de l'application, nous pouvons donc obtenir le contexte de l'application correspondante via le nom du package d'application. Une autre chose à noter est que la condition préalable pour savoir si les fichiers SP d'autres applications peuvent être lus et écrits est que le fichier SP spécifie un fichier lisible ou Les autorisations en écriture ne sont pas autorisées si celle que nous avons créée ci-dessus est MODE_PRIVATE ~ Vous êtes donc comme lire les données dans le SP de quelqu'un d'autre. C'est difficile. De plus, certaines informations clés, telles que les mots de passe enregistrés dans SP, sont généralement cryptées, vous ne pouvez donc écrire et jouer que par vous-même. Je parlerai plus tard de la méthode de cryptage MD5 couramment utilisée !

Organigramme de mise en œuvre :

5.png

Exemple de code :

Exécution des rendus :

6.png

Implémentation du code :

Notre opération de lecture de SP est placée dans MainActivity.java Terminé dans , cliquez sur le bouton pour lire le SP et l'afficher via Toast :

public class MainActivity extends AppCompatActivity {

    private Context othercontext;
    private SharedPreferences sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btnshow = (Button) findViewById(R.id.btnshow);
        btnshow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获得第一个应用的包名,从而获得对应的Context,需要对异常进行捕获
                try {
                    othercontext = createPackageContext("com.jay.sharedpreferencedemo", Context.CONTEXT_IGNORE_SECURITY);
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }
                //根据Context取得对应的SharedPreferences
                sp = othercontext.getSharedPreferences("mysp", Context.MODE_WORLD_READABLE);
                String name = sp.getString("username", "");
                String passwd = sp.getString("passwd", "");
                Toast.makeText(getApplicationContext(), "Demo1的SharedPreference存的\n用户名为:" + name + "\n密码为:" + passwd, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

3. Utilisez MD5 pour crypter les données importantes de SharedPreference

Hé, qu'est-ce que nous avons. ci-dessus De cette manière, le mot de passe du compte est enregistré directement sur le SP. Si le téléphone n'est pas rooté, les autres applications ne pourront pas accéder au téléphone. Si vous êtes rooté et que les données sont obtenues par d'autres applications, ce qui entraîne des conséquences, alors... vous n'avez pas à nous en vouloir, haha, Qui vous a dit de rooter~, nous n'en prenons pas la responsabilité, c'est vrai ! Mais en tant que développeur d'applications responsable, nous ne pouvons pas toujours Est-ce vrai ? Nous pouvons utiliser certains algorithmes de cryptage pour crypter les mots de passe des utilisateurs. De plus, nous chiffrons généralement les mots de passe des utilisateurs ! Ci-dessous, nous dessinons un diagramme simple pour aider tout le monde à comprendre le processus de traitement de cryptage :

1. Le processus de traitement de cryptage simple

L'organigramme est le suivant  :

7.png

Analyse des organigrammes  :

  • Étape 1. L'utilisateur enregistre le mot de passe du compte une fois le mot de passe du compte vérifié (si le compte est dupliqué, le nombre de chiffres du mot de passe > 6 chiffres, etc.) , Autrement dit, le mot de passe du compte est valide. Après une inscription réussie, nous soumettons le numéro de compte au serveur et le mot de passe crypté localement !
  • Étape 2. Le serveur enregistre le numéro de compte et le mot de passe crypté soumis par l'utilisateur dans la base de données du serveur, c'est-à-dire le service. Le client n'enregistre pas notre mot de passe en texte clair (original) !
  • Étape 3. De retour au client, si l'enregistrement est réussi ou la connexion est réussie, vous souhaitez enregistrer le mot de passe du compte sur le SP, le mot de passe enregistré. Vous devez également passer par le processus de cryptage ! C'est-à-dire un mot de passe en texte brut ——> Chiffrez, puis enregistrez ! Si vous ne l'enregistrez pas, le mot de passe en texte clair sera utilisé à chaque fois que vous le demanderez. Vous devez également suivre le processus à la maison, puis utiliser le mot de passe crypté pour demander le serveur !
  • Étape 4. Le serveur vérifie le compte et le mot de passe crypté en cas de succès, le client se voit attribuer un identifiant de session, qu'il peut conserver plus tard. Cette session permet d'accéder aux services associés fournis par le serveur !

Hé, vous comprenez, il existe de nombreuses méthodes de cryptage Xiaozhu n'est pas un expert dans ce domaine. La méthode de cryptage utilisée auparavant est MD5. Cryptage, cette section vous donne également une brève introduction à ce cryptage MD5 et une démonstration de son utilisation~

2 Une brève introduction à MD5 :

1) Qu'est-ce que MD5 ? :

Réponse : L'algorithme de résumé de message MD5 (le nom chinois est Message Digest Algorithm Fifth Edition) est largement utilisé dans le domaine de la sécurité informatique. Une fonction de hachage utilisée pour assurer la protection de l'intégrité des messages - extraite de "Baidu Encyclopedia" Pour faire simple, il s'agit d'un algorithme de cryptage capable de crypter une chaîne, un fichier ou un package compressé à l'aide de MD5. Vous pouvez produire une chaîne d’une longueur fixe de 128 bits ! Cette chaîne est fondamentalement unique ! De plus, nous le savons tous : un hexadécimal Il doit être représenté par 4 bits, alors la longueur de chaîne MD5 correspondante est : 128 / 4 = 32 bits ! Une autre possibilité Vous voyez que certains md5 sont de 16 bits, mais les huit premiers et huit derniers bits du code MD5 de 32 bits sont supprimés ! N'y crois pas, essayons Baidu : décryptage md5 en ligne, le premier : http://www.cmd5.com/

8.png

2) MD5 peut-il être cracké ?

Réponse : MD5 est irréversible, ce qui signifie qu'il n'y a pas d'algorithme correspondant et que les données originales ne peuvent pas être obtenues de manière inverse à partir de la valeur md5 générée ! Bien sûr, à l'exception du craquage par force brute, vous pouvez vérifier la bibliothèque MD5 après un simple cryptage MD5~

3) La valeur MD5 est-elle unique ?

Réponse : Pas unique. Une donnée originale ne correspond qu'à une seule valeur MD5, mais une valeur MD5 peut correspondre à plusieurs données originales !


3. Exemple d'implémentation du cryptage MD5 :

En fait, il existe de nombreux exemples MD5 bien écrits sur Internet. Vous pouvez en rechercher beaucoup sur Baidu ou. Google. Voici la classe d'outils de chiffrement MD5 des petits cochons utilisée !

Md5Util.java :

/**
 * Created by Jay on 2015/9/2 0002.
 */
public class MD5 {
    public static String getMD5(String content) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(content.getBytes());
            return getHashString(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getHashString(MessageDigest digest) {
        StringBuilder builder = new StringBuilder();
        for (byte b : digest.digest()) {
            builder.append(Integer.toHexString((b >> 4) & 0xf));
            builder.append(Integer.toHexString(b & 0xf));
        }
        return builder.toString();
    }
}

MainActivity.java appelle directement la méthode statique getMD5 :

Log.e("HeHe", MD5.getMD5("呵呵"));

On voit que le Logcat affiche :

9.png

C'est ce qui se passe après le cryptage. Nous pouvons copier cette chaîne de texte chiffré sur le site Web de décryptage en ligne md5 ci-dessus :

10.png

Hé, bien sûr, c'est juste crypté une fois comme ça. crackez-le directement. Cela semble un peu dangereux, alors cryptez-le simplement 100 fois. C'est-à-dire crypter à nouveau la chaîne cryptée et la répéter 100 fois. Nous ajoutons une méthode pour la crypter cent fois sur la base d'origine :

public static String getMD5x100(String content){
    String s1 = content;
    for(int i = 0;i < 100;i++){
        s1 = getMD5(s1);
    }
    return s1;
}

Ensuite, appelez-la et trouvez le journal qui imprime ceci :

11.png

Sur le site Web de l'interface de copie :

12.png

D'accord, installé B avec succès~


4. Classe d'outils SharedPreference :

Il doit être très difficile d'instancier vous-même les classes liées à SP à chaque fois. Voici une classe d'outils pour SP, vous pouvez la publier. Dans mon propre projet, la classe d'outils provient du blog de Hong Yang~

SPUtils.java

package com.jay.sharedpreferencedemo3;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.Map;

/**
 * Created by Jay on 2015/9/2 0002.
 */
public class SPUtils {
    /**
     * 保存在手机里的SP文件名
     */
    public static final String FILE_NAME = "my_sp";

    /**
     * 保存数据
     */
    public static void put(Context context, String key, Object obj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        if (obj instanceof Boolean) {
            editor.putBoolean(key, (Boolean) obj);
        } else if (obj instanceof Float) {
            editor.putFloat(key, (Float) obj);
        } else if (obj instanceof Integer) {
            editor.putInt(key, (Integer) obj);
        } else if (obj instanceof Long) {
            editor.putLong(key, (Long) obj);
        } else {
            editor.putString(key, (String) obj);
        }
        editor.commit();
    }


    /**
     * 获取指定数据
     */
    public static Object get(Context context, String key, Object defaultObj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        if (defaultObj instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObj);
        } else if (defaultObj instanceof Float) {
            return sp.getFloat(key, (Float) defaultObj);
        } else if (defaultObj instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObj);
        } else if (defaultObj instanceof Long) {
            return sp.getLong(key, (Long) defaultObj);
        } else if (defaultObj instanceof String) {
            return sp.getString(key, (String) defaultObj);
        }
        return null;
    }

    /**
     * 删除指定数据
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        editor.commit();
    }


    /**
     * 返回所有键值对
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        Map<String, ?> map = sp.getAll();
        return map;
    }

    /**
     * 删除所有数据
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.commit();
    }

    /**
     * 检查key对应的数据是否存在
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        return sp.contains(key);
    }

}

5.

SharedPreferenceDemo.zipTélécharger SharedPreferenceDemo.zipSharedPreferenceDemo2.zipTélécharger SharedPreferenceDemo2.zipSharedPreferenceDemo3.zip  : Téléchargez SharedPreferenceDemo3.zip


Résumé de cette section :

D'accord, à propos de la deuxième façon dont Android stocke les données : SharedPreference Voilà pour enregistrer les paramètres de préférence de l'utilisateur. Il devrait pouvoir répondre à vos besoins de développement et d'utilisation quotidiens de SP S'il manque quelque chose, n'hésitez pas à le mentionner, merci~

.