Android学习笔记(4)——登陆界面模拟及存储文件到内存

本文介绍如何在安卓应用中实现“记住登录用户名密码”的功能,包括界面设计、使用线性布局与相对布局实现布局文件、MainActivity代码解析及文件存储原理。

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

搬运自本人博客:xge技术博客

原文:http://www.xgezhang.com/android_login_save_file.html


在本机或服务器上保存文件是比较简单的一件事,那么在安卓系统下我们该如何存储文件呢?这里我们借用登陆界面常见的“记住登陆用户名密码”的为例,来介绍一下如何把文件保存到手机内存,也综合复习和练习一下之前的内容:

首先我们还是先做界面:

Android学习笔记(4)——登陆界面模拟及存储文件到内存-xge技术博客

对应的xml布局文件如下,采用的是线性布局加上相对布局来实现的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
< 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 = "fill_parent"
     android:orientation = "vertical"
     tools:context = "com.xgezhang.login.MainActivity" >
 
     < TextView
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:text = "@string/please_input_user_name" />
 
     < EditText
         android:id = "@+id/et_username"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:singleLine = "true" />
 
     < TextView
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:text = "@string/please_input_password" />
 
     < EditText
         android:id = "@+id/et_password"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:singleLine = "true"
         android:password = "true" />
 
     < RelativeLayout
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content" >
 
         < TextView
             android:id = "@+id/tv_remenber_user_info"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:layout_centerVertical = "true"
             android:text = "@string/remenber_user_info" />
 
         < CheckBox
             android:id = "@+id/cb"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:layout_toRightOf = "@id/tv_remenber_user_info"
             android:checked = "true" />
 
         < Button
             android:id = "@+id/bt_login"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:layout_alignParentRight = "true"
             android:text = "@string/bt_login" />
     </ RelativeLayout >
 
</ LinearLayout >

以上xml很容易理解,只是注意以下几点:

  1. Edittext要设置为singleLine=true;
  2. 密码内容要设置password=true,不然会是明文显示;
  3. Checkbox中可以通过指定checked参数的值来选择默认勾选情况;

接下来我们来看MainActivity代码,稍微理下思路:我们首先需要注册一个登陆按钮的事件,当点击登陆按钮之后,会读取et_username和et_password的值,判断是否为空,如果不为空,则验证是否是正确的用户名和密码。同时,如果我们选择了保存用户登陆信息,则需要把用户名密码通过文本的方式存储到手机中。

当然,每次程序运行的时候,会自动读取这个文本,如果文本中有内容,则自动填写到两个EditText里面,相当于保存内容的回显。

接下来我们来看看代码,因为这里只是模拟登陆,并不是真正的把数据发送到服务器再从database里面select并验证,所以就采用很基本的方式判断了。

MainActivity.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.xgezhang.login;
 
import java.util.HashMap;
import java.util.Map;
 
import com.xgezhang.login.service.loginService;
 
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
 
public class MainActivity extends Activity implements OnClickListener {
 
     private static final String TAG = "MainActivity" ;
     private EditText et_username;
     private EditText et_password;
     private CheckBox cb;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         et_username = (EditText) findViewById(R.id.et_username);
         et_password = (EditText) findViewById(R.id.et_password);
         cb = (CheckBox) findViewById(R.id.cb);
         
         Map <String,String> userInfoMap = loginService.getUserInfoMap( this );
         //回显用户已经保存的登陆数据
         if (userInfoMap!= null ){
             et_username.setText(userInfoMap.get( "username" ));
             et_password.setText(userInfoMap.get( "password" ));
         }
         
         Button bt_login = (Button) findViewById(R.id.bt_login);
         bt_login.setOnClickListener( this ); 
     }
 
     @Override
     public void onClick(View v) {
         switch (v.getId()) {
         case R.id.bt_login:
             // 登陆事件
             String username = et_username.getText().toString().trim();
             String password = et_password.getText().toString().trim();
             if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
                 Toast.makeText( this , "用户名或密码为空" , Toast.LENGTH_SHORT).show();
             } else {
                 if (cb.isChecked()) {
                     boolean result = loginService.saveUserInfo( this , username, password);
                     if (result){
                         Toast.makeText( this , "登陆信息已保存" , Toast.LENGTH_SHORT).show();
                     } else {
                         Toast.makeText( this , "登陆信息保存异常" , Toast.LENGTH_SHORT).show();
                     }
                 }
                 
                 if (username.equals( "zhangsan" ) && password.equals( "123456" )) {
                     Toast.makeText( this , "登陆成功" , Toast.LENGTH_SHORT).show();
                 } else {
                     Toast.makeText( this , "登陆失败,用户名或密码错误" , Toast.LENGTH_SHORT).show();
                 }
             }
             break ;
         default :
             break ;
         }
     }
}

其中有两个函数是需要我们进一步实现的,分别是saveUserInfo和getUserInfoMap。出于方便的目的,我们新建一个package命名为com.xgezhang.login.service,并新建一个class名为loginService,来存放登陆会用到的一些函数。

我们先介绍saveUserInfo函数,这里涉及到安卓系统数据保存的问题。我们需要知道的是,在Android系统下有一个/data/data路径,这里存放了所有安装的app的数据,在Eclipse中我们可以通过DDMS来查看:

Android学习笔记(4)——登陆界面模拟及存储文件到内存-xge技术博客

每个app对应的文件夹里面默认有files和cache,其中cache用于存储缓存文件。

了解了存储的原理,我们就可以开始写代码了:

?
1
2
3
4
5
6
7
8
9
10
11
12
static public boolean saveUserInfo(Context context, String username,String password) {
         try {
             File file = new File(context.getFilesDir(), "userinfo.txt" );
             FileOutputStream fos = new FileOutputStream(file);
             fos.write((username + "###" + password).getBytes());
             fos.close();
             return true ;
         } catch (Exception e) {
             e.printStackTrace();
             return false ;
         }
     }

上述代码比较容易理解,和Java中文件操作没有两样,只是注意几个问题,一个是new File的路径不建议写成固定的路径,而是通过传递一个context,通过context.getFilesDir()函数来直接获取路径;另外,由于有文件的操作,这里需要加上try块来避免异常,并且如果出现异常将其catch掉,并返回false,供调用函数去判断。

这里的用户名密码是通过“###”符号来分割的,肯定是不太合理的,这里不用深究。

接下来是getUserInfoMap函数,和上述代码差不多,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static public Map<String,String> getUserInfoMap(Context context){
         try {
             File file = new File(context.getFilesDir(), "userinfo.txt" );
             FileInputStream fis = new FileInputStream(file);
             BufferedReader br = new BufferedReader( new InputStreamReader(fis));
             String str = br.readLine();
             String[] userinfos = str.split( "###" );
             Map<String, String> map = new HashMap<String, String>();
             map.put( "username" , userinfos[ 0 ]);
             map.put( "password" ,userinfos[ 1 ]);
             return map;
             
         } catch (Exception e) {
             e.printStackTrace();
             return null ;
         }
}

这里的异常是返回null,所以外部只用判断返回的Map是否为null即可。

另外,由于这两个函数显然都不需要将类实体化,所以我们可以直接写成static,在Android项目中推荐大家使用static函数,可以提高程序运行效率。

完整的loginService.java代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.xgezhang.login.service;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
 
import android.R.string;
import android.content.Context;
 
public class loginService {
     /**
      * @param context 上下文
      * @param username 用户名
      * @param password 密码
      * @return boolean  true表示保存成功 false表示保存失败
      */
     static public boolean saveUserInfo(Context context, String username,String password) {
         try {
             File file = new File(context.getFilesDir(), "userinfo.txt" );
             FileOutputStream fos = new FileOutputStream(file);
             fos.write((username + "###" + password).getBytes());
             fos.close();
             return true ;
         } catch (Exception e) {
             e.printStackTrace();
             return false ;
         }
     }
     /**
      * 获取用户保存的登陆信息
      * @param context
      * @return Map
      */
     static public Map<String,String> getUserInfoMap(Context context){
         try {
             File file = new File(context.getFilesDir(), "userinfo.txt" );
             FileInputStream fis = new FileInputStream(file);
             BufferedReader br = new BufferedReader( new InputStreamReader(fis));
             String str = br.readLine();
             String[] userinfos = str.split( "###" );
             Map<String, String> map = new HashMap<String, String>();
             map.put( "username" , userinfos[ 0 ]);
             map.put( "password" ,userinfos[ 1 ]);
             return map;
             
         } catch (Exception e) {
             e.printStackTrace();
             return null ;
         }
     }
}

至此,程序结束,可以用虚拟机运行测试一下。

欢迎转载,请注明出处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值