基于Android的记账系统软件

基于Android的记账系统软件

  1. 系统的需求分析

1.1系统目标

随着生活节奏的加快和消费方式的多样化,人们对于个人财务状况的把控需求日益增长。传统的记账方式,如纸笔记录或简单的电子表格记录,不仅效率低下,而且难以进行数据的分析和整理。为了改变这一现状,我开发了这款记账 App,旨在帮助用户更轻松、更科学地管理个人财务,实现财务状况的清晰掌握和合理规划。

在数字化时代,个人财务管理变得越来越重要。为了帮助用户轻松管理个人财务,我精心打造了这款基于 Java 语言开发的 Android 记账 App。它凭借 Java 语言强大的功能和稳定性,结合先进的 Android 开发技术,为用户提供了一个高效、便捷、安全的记账平台,满足用户在日常生活中的各种记账需求。

1.2功能需求

该软件应该具有以下功能:

注册登录:用户可以通过简单的注册流程创建自己的专属账号,登录后数据将得到安全存储,方便随时在不同设备上同步使用。登录过程快速便捷,采用加密技术保障用户账号信息的安全。

新增收入:支持用户快速记录每一笔收入,详细填写收入来源、金额、日期等信息,操作界面简洁明了,便于用户快速完成记录。

收入明细:用户能够随时查看自己的收入明细,按照时间顺序或收入来源进行分类展示,清晰呈现每一笔收入的详细情况,方便用户了解自己的收入结构和变化趋势。

新增支出:同样提供便捷的操作界面,用户可以轻松记录每一笔支出,包括支出项目、金额、消费地点、支付方式等信息,全面记录生活中的每一笔开销。

支出明细:对支出数据进行详细整理和展示,用户可以按照不同维度查看支出明细,如按时间、类别、金额等进行筛选,从而深入了解自己的消费习惯和支出情况。

数据分析图表:通过直观的数据分析图表,如柱状图、折线图、饼图等,将用户的收入和支出数据进行可视化展示。用户可以一目了然地了解自己的财务状况,快速发现消费趋势和潜在问题,为制定合理的理财计划提供依据。

密码修改:为了保障用户账号的安全,App 提供了密码修改功能。用户可以根据自己的需求随时修改登录密码,确保账号信息的安全性。

 

  1. 系统的概要设计

该软件是一款是基于Android开发的手机应用,简单实用,易于上手。

2.1 运行环境

Java 语言开发:Java 语言具有丰富的类库和强大的生态系统,使得开发过程更加高效,应用程序具有更好的可维护性和扩展性。借助 Java 的特性,我们能够快速实现各种复杂的功能,同时保证应用在不同 Android 设备上的稳定运行。

SQLite 数据库:采用 SQLite 数据库对用户的记账数据进行存储和管理。SQLite 具有轻量级、高性能、占用资源少等优点,能够快速读写数据,确保应用在处理大量记账数据时的高效性和稳定性。无论是频繁的记录操作还是复杂的数据分析,都能轻松应对。

RecyclerView 列表展示:使用 RecyclerView 进行收入和支出明细的列表展示,具有高度的灵活性和高效的性能。RecyclerView 能够根据屏幕大小和设备性能自动优化布局,快速加载和显示大量数据,同时支持各种动画效果和交互操作,为用户带来流畅的视觉体验。

2.2 数据库表设计

 

  1. 设计与实现部分

运行画面截图

 

关键代码:

DataAnalyseActivity

package com.example.zhangbu.activity;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import com.example.zhangbu.R;
import com.example.zhangbu.db.MyDBHelper;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.ArrayList;
import java.util.List;
public class DataAnalyseActivity extends AppCompatActivity {
    //1 定义对象
    LineChart income_chart,outpay_chart;
    MyDBHelper mhelper;
    SQLiteDatabase db;
    String[] indata={"学习-奖金","补助-奖金","比赛-奖励","业余-兼职","基本-工资","福利-分红","加班-津贴","其他"};
    //收入类型数据统计的初始值
    int xxjjmoney=0;
    int bzjjmoney=0;
    int bsjlmoney=0;
    int yyjzmoney=0;
    int jbgzmoney=0;
    int flfhmoney=0;
    int jbjtmoney=0;
    int qtmoney=0;
    String[] outdata={"电影-娱乐","美食-畅饮","欢乐-购物","手机-充值","交通-出行","教育-培训","社交-礼仪","生活-日用","其他"};
    //收入类型数据统计的初始值
    int dyylmoney=0;
    int mscymoney=0;
    int hlgwmoney=0;
    int sjczmoney=0;
    int jtcxmoney=0;
    int jypxmoney=0;
    int sjlymoney=0;
    int shrymoney=0;
    int othermoney=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_data_analyse);
        //2 绑定控件
        initView();
        //3 收入汇总分析
        inComeData();
        //4 支出汇总分析
        outComeData();
    }//2 绑定控件---------------代码
    private void initView() {
        income_chart=findViewById(R.id.income_chart_data);
        outpay_chart=findViewById(R.id.outpay_chart_data);
        mhelper=new MyDBHelper(DataAnalyseActivity.this);
        db=mhelper.getWritableDatabase();
    }
    //3 收入汇总分析-------------------代码
    private void inComeData() {
        //第一部分:获取数据
        Cursor cursor =db.rawQuery("select * from in_come",null);
        while(cursor.moveToNext()){
            @SuppressLint("Range") Double mymoney=cursor.getDouble(cursor.getColumnIndex("inmoney"));
            @SuppressLint("Range") String mytype=cursor.getString(cursor.getColumnIndex("intype"));
            if(mytype.equals("学习-奖金")){
                xxjjmoney+=mymoney;
            }else if(mytype.equals("补助-奖金")){
                bzjjmoney+=mymoney;
            }else if(mytype.equals("比赛-奖励")){
                bzjjmoney+=mymoney;
            }else if(mytype.equals("业余-兼职")){
                yyjzmoney+=mymoney;
            }else if(mytype.equals("基本-工资")){
                jbgzmoney+=mymoney;
            }else if(mytype.equals("福利-分红")){
                flfhmoney+=mymoney;
            }else if(mytype.equals("加班-津贴")){
                jbjtmoney+=mymoney;
            }else if(mytype.equals("其他")){
                qtmoney+=mymoney;
            }
        }
        //第二部分:LineChart 图表初始化设置---Xy 轴的设置
        XAxis xAxis=income_chart.getXAxis();//获取此图表的 x 轴轴线
        YAxis yAxisleft =income_chart.getAxisLeft();//获取此图表的 Y 轴左侧轴线
        YAxis yAxisright =income_chart.getAxisRight();//获取此图表的 Y轴右侧轴线
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置 X 轴线的位置为底部
        yAxisleft.setAxisMinimum(0f);//保证 Y 轴从 0 开始,不然会上移一点。
        yAxisright.setAxisMinimum(0f);
        xAxis.setValueFormatter(new IAxisValueFormatter() {//x 轴自定义标签的设置
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return indata[(int) v];
            }
        });
        //第三部分:LineDataSet 曲线初始化设置
        List<Entry> inentries=new ArrayList<>();//Y 轴的数据
        inentries.add(new Entry(0,xxjjmoney));
        inentries.add(new Entry(1,bzjjmoney));
        inentries.add(new Entry(2,bsjlmoney));
        inentries.add(new Entry(3,yyjzmoney));
        inentries.add(new Entry(4,jbgzmoney));
        inentries.add(new Entry(5,flfhmoney));
        inentries.add(new Entry(6,jbjtmoney));
        inentries.add(new Entry(7,qtmoney));
        LineDataSet lineDataSet=new LineDataSet(inentries,"金额");//代表一条线,“金额是曲线名称
        lineDataSet.setValueTextSize(25);//曲线上文字的大小
        lineDataSet.setValueTextColor(Color.WHITE);//曲线上文字的颜色
        lineDataSet.setDrawFilled(true);//设置折线图填充
        //第四部分:曲线展示
        LineData data=new LineData(lineDataSet);//创建 LineData 对象 属于LineChart 折线图的数据集合
        income_chart.setData(data);// 添加到图表中
    }
    //4 支出汇总分析--------------------代码
    private void outComeData() {
        //第一部分:获取数据
        Cursor cursor =db.rawQuery("select * from out_pay",null);
        while(cursor.moveToNext()){
            @SuppressLint("Range") Double mymoney=cursor.getDouble(cursor.getColumnIndex("outmoney"));
            @SuppressLint("Range") String mytype=cursor.getString(cursor.getColumnIndex("outtype"));
            if(mytype.equals("电影-娱乐")){
                dyylmoney+=mymoney;
            }else if(mytype.equals("美食-畅饮")){
                mscymoney+=mymoney;
            }else if(mytype.equals("欢乐-购物")){
                hlgwmoney+=mymoney;
            }else if(mytype.equals("手机-充值")){
                sjczmoney+=mymoney;
            }else if(mytype.equals("交通-出行")){
                jtcxmoney+=mymoney;
            }else if(mytype.equals("教育-培训")){
                jypxmoney+=mymoney;
            }else if(mytype.equals("社交-礼仪")){
                sjlymoney+=mymoney;
            }else if(mytype.equals("生活-日用")){
                shrymoney+=mymoney;
            }else if(mytype.equals("其他")){
                othermoney+=mymoney;
            }
        }
        //第二部分:LineChart 图表初始化设置---Xy 轴的设置
        XAxis xAxis=outpay_chart.getXAxis();//获取此图表的 x 轴轴线
        YAxis yAxisleft =outpay_chart.getAxisLeft();//获取此图表的 Y 轴左侧轴线
        YAxis yAxisright =outpay_chart.getAxisRight();//获取此图表的 Y 轴右侧轴线
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置 X 轴线的位置为底部
        yAxisleft.setAxisMinimum(0f);//保证 Y 轴从 0 开始,不然会上移一点。
        yAxisright.setAxisMinimum(0f);
        xAxis.setValueFormatter(new IAxisValueFormatter() {//x 轴自定义标签的设置
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return outdata[(int) v];
            }
        });
        //第三部分:LineDataSet 曲线初始化设置
        List<Entry> outentries=new ArrayList<>();//Y 轴的数据
        outentries.add(new Entry(0,dyylmoney));
        outentries.add(new Entry(1,mscymoney));
        outentries.add(new Entry(2,hlgwmoney));
        outentries.add(new Entry(3,sjczmoney));
        outentries.add(new Entry(4,jtcxmoney));
        outentries.add(new Entry(5,jypxmoney));
        outentries.add(new Entry(6,sjlymoney));
        outentries.add(new Entry(7,shrymoney));
        outentries.add(new Entry(8,othermoney));
        LineDataSet lineDataSet=new LineDataSet(outentries,"金额");//代表一条线,“金额是曲线名称
        lineDataSet.setValueTextSize(25);//曲线上文字的大小
        lineDataSet.setValueTextColor(Color.WHITE);//曲线上文字的颜色
        lineDataSet.setDrawFilled(true);//设置折线图填充
        //第四部分:曲线展示
        LineData data=new LineData(lineDataSet);//创建 LineData 对象 属于LineChart 折线图的数据集合
        outpay_chart.setData(data);// 添加到图表中
    }
}

InComeDetailActivity

package com.example.zhangbu.activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import android.annotation.SuppressLint;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;

import com.example.zhangbu.R;
import com.example.zhangbu.adapter.IncomeAdapter;
import com.example.zhangbu.bean.IncomeBean;
import com.example.zhangbu.db.MyDBHelper;

import java.util.ArrayList;
import java.util.List;

public class InComeDetailActivity extends AppCompatActivity {
    //1 定义对象
    RecyclerView recy_view;
    MyDBHelper mhelper;
    SQLiteDatabase db;
    List<IncomeBean> arr1=new ArrayList();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_in_come_detail);
        //2 绑定控件
        initView();
        //3 准备数据
        initData();
        //4 设计每一行的子布局
        //5 定义适配器: 数据和子布局关联起来(桥梁的作用)
        IncomeAdapter adapter=new IncomeAdapter(InComeDetailActivity.this,arr1);
        //6 将适配器和布局管理器加载到控件当中
        StaggeredGridLayoutManager st=new StaggeredGridLayoutManager(StaggeredGridLayoutManager.VERTICAL,1);
        recy_view.setLayoutManager(st);
        recy_view.setAdapter(adapter);
    }
    //2 绑定控件----------------代码
    private void initView() {
        recy_view=findViewById(R.id.recy_view_indetail);
        mhelper=new MyDBHelper(InComeDetailActivity.this);
        db=mhelper.getWritableDatabase();
    }
    //3 准备数据----------------代码
    private void initData() {
        //从数据库查询所有的新增收入信息,取出数据
        Cursor cursor=db.rawQuery("select * from in_come",null);
        while(cursor.moveToNext()){
            @SuppressLint("Range") int myid=cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") double mymoney=cursor.getDouble(cursor.getColumnIndex("inmoney"));
            @SuppressLint("Range") String mytime=cursor.getString(cursor.getColumnIndex("intime"));
            @SuppressLint("Range") String mytype=cursor.getString(cursor.getColumnIndex("intype"));
            @SuppressLint("Range") String mypayer=cursor.getString(cursor.getColumnIndex("inpayer"));
            @SuppressLint("Range") String myremark=cursor.getString(cursor.getColumnIndex("inremark"));
            IncomeBean incomeBean=new IncomeBean( myid,mymoney,mytime,mytype,mypayer,myremark);
            arr1.add(incomeBean);
        }
    }
}

NewInComeActivity

package com.example.zhangbu.activity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.zhangbu.R;
import com.example.zhangbu.db.MyDBHelper;
import com.example.zhangbu.view.MainActivity;

public class NewInComeActivity extends AppCompatActivity {
    //1 定义对象
    EditText et_money,et_time,et_payer,et_remark;
    Spinner sp_type;
    Button bt_sava,bt_cancel;
    MyDBHelper mhelper;
    SQLiteDatabase db;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_in_come);
        //2 绑定控件
        initView();
        //3 保存按钮功能的实现
        btnSave();
        //4 取消按钮功能的实现
        btnCancel();

    }
    //2 绑定控件-------------------代码
    private void initView() {
        et_money=findViewById(R.id.et_money_newin);
        et_time=findViewById(R.id.et_time_newin);
        sp_type=findViewById(R.id.sp_type_newin);
        et_payer=findViewById(R.id.et_payer_newin);
        et_remark=findViewById(R.id.et_remark_newin);
        bt_sava=findViewById(R.id.bt_save_newin);
        bt_cancel=findViewById(R.id.bt_cancel_newin);
        mhelper=new MyDBHelper(NewInComeActivity.this);
        db=mhelper.getWritableDatabase();
    }
    //3 保存按钮功能的实现--------代码
    private void btnSave() {
        bt_sava.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取输入的内容保存到数据库的收入表中
                ContentValues values=new ContentValues();
                values.put("inmoney",et_money.getText().toString());
                values.put("intime",et_time.getText().toString());
                values.put("intype",sp_type.getSelectedItem().toString());
                values.put("inpayer",et_payer.getText().toString());
                values.put("inremark",et_remark.getText().toString());
                db.insert("in_come",null,values);
                Toast.makeText(NewInComeActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                //刷新本页面
                Intent intent=new Intent(NewInComeActivity.this,NewInComeActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
    //4 取消按钮功能的实现--------代码
    private void btnCancel() {
        bt_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(NewInComeActivity.this,
                        MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

NewInComeActivity

package com.example.zhangbu.activity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.example.zhangbu.R;
import com.example.zhangbu.db.MyDBHelper;
import com.example.zhangbu.view.MainActivity;
public class NewPayActivity extends AppCompatActivity {
    //定义对象
    EditText et_money,et_time,et_payer,et_remark;
    Spinner sp_type;
    Button bt_sava,bt_cancel;
    MyDBHelper mhelper;
    SQLiteDatabase db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_pay);
        //2 绑定控件
        initView();
        //3 保存按钮功能的实现
        btnSave();
        //4 取消按钮功能的实现
        btnCancel();
    }
    //2 绑定控件-------------------代码
    private void initView() {
        et_money=findViewById(R.id.et_money_newout);
        et_time=findViewById(R.id.et_time_newout);
        sp_type=findViewById(R.id.sp_type_newout);
        et_payer=findViewById(R.id.et_payer_newout);
        et_remark=findViewById(R.id.et_remark_newout);
        bt_sava=findViewById(R.id.bt_save_newout);
        bt_cancel=findViewById(R.id.bt_cancel_newout);
        mhelper=new MyDBHelper(NewPayActivity.this);
        db=mhelper.getWritableDatabase();
    }
    //3 保存按钮功能的实现--------代码
    private void btnSave() {
        bt_sava.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取输入的内容保存到数据库的收入表中
                ContentValues values=new ContentValues();
                values.put("outmoney",et_money.getText().toString());
                values.put("outtime",et_time.getText().toString());
                values.put("outtype",sp_type.getSelectedItem().toString());
                values.put("outpayee",et_payer.getText().toString());
                values.put("outremark",et_remark.getText().toString());
                db.insert("out_pay",null,values);
                Toast.makeText(NewPayActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                //刷新本页面
                Intent intent=new Intent(NewPayActivity.this,NewPayActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
    //4 取消按钮功能的实现--------代码
    private void btnCancel() {
        bt_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(NewPayActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

PayDetailActivity

package com.example.zhangbu.activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.annotation.SuppressLint;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.Button;
import com.example.zhangbu.R;
import com.example.zhangbu.adapter.OutpayAdapter;
import com.example.zhangbu.bean.Outpaybean;
import com.example.zhangbu.db.MyDBHelper;
import java.util.ArrayList;
import java.util.List;
public class PayDetailActivity extends AppCompatActivity {
    RecyclerView recy_view;
    MyDBHelper mhelper;
    SQLiteDatabase db;
    List<Outpaybean> arr1 = new ArrayList();
    private Button mBtBack;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pay_detail);
        initView();
        initData();
        OutpayAdapter adapter=new OutpayAdapter(PayDetailActivity.this,arr1);
        //6 将适配器和布局管理器加载到控件当中
        StaggeredGridLayoutManager st=new StaggeredGridLayoutManager(StaggeredGridLayoutManager.VERTICAL,1);
        recy_view.setLayoutManager(st);
        recy_view.setAdapter(adapter);
    }
    private void initView() {
        recy_view=findViewById(R.id.recy_view_outdetail);
        mhelper=new MyDBHelper(PayDetailActivity.this);
        db=mhelper.getWritableDatabase();
    }
    private void initData() {
        //从数据库查询所有的新增收入信息,取出数据
        Cursor cursor = db.rawQuery("select * from out_pay", null);
        while (cursor.moveToNext()) {
            @SuppressLint("Range") int myid = cursor.getInt(cursor.getColumnIndex("id"));
            @SuppressLint("Range") double mymoney = cursor.getDouble(cursor.getColumnIndex("outmoney"));
            @SuppressLint("Range") String mytime = cursor.getString(cursor.getColumnIndex("outtime"));
            @SuppressLint("Range") String mytype = cursor.getString(cursor.getColumnIndex("outtype"));
            @SuppressLint("Range") String mypayer = cursor.getString(cursor.getColumnIndex("outpayee"));
            @SuppressLint("Range") String myremark = cursor.getString(cursor.getColumnIndex("outremark"));
            Outpaybean outpaybean = new Outpaybean(myid, mymoney, mytime, mytype, mypayer, myremark);
            arr1.add(outpaybean);
        }
    }}

SysSettingActivity

package com.example.zhangbu.activity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.zhangbu.R;
import com.example.zhangbu.db.MyDBHelper;
import com.example.zhangbu.view.LoginActivity;
import com.example.zhangbu.view.MainActivity;

public class SysSettingActivity extends AppCompatActivity {
    //1 定义对象
    TextView txt_user;//创建一个显示用户名的文本对象
    EditText et_ypwd, et_xpwd, et_zxpwd;// 创建三个 EditText 对象
    Button bt_modify, bt_cancel;// 创建两个 Button 对象
    MyDBHelper mhelper;
    SQLiteDatabase db;
    String name;
    String pwd;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sys_setting);
        //第二步:绑定控件
        initView();
        //第三步:显示当前登录的用户名
        displayInfo();
        //第四步:修改按钮功能
        btnModify();
        //第五步:取消按钮功能
        btncancel();
    }
    //第二步:绑定控件-----------------代码
    private void initView() {
        txt_user=findViewById(R.id.txt_name_sys);
        et_ypwd=findViewById(R.id.et_ypwd_sys);
        et_xpwd=findViewById(R.id.et_xpwd_sys);
        et_zxpwd=findViewById(R.id.et_zxpwd_sys);
        bt_modify=findViewById(R.id.bt_modify_sys);
        bt_cancel=findViewById(R.id.bt_cancel_sys);
        mhelper=new MyDBHelper(SysSettingActivity.this);
        db=mhelper.getWritableDatabase();
    }
    //第三步:显示当前登录的用户名-------代码
    private void displayInfo() {

        name=getSharedPreferences("userinfo",0).getString("username","");

        pwd=getSharedPreferences("userinfo",0).getString("userpwd","");
        txt_user.setText(name);
    }
    //第四步:修改按钮功能----------------------代码
    private void btnModify() {
        bt_modify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取三个输入框中的内容
                String ypwd = et_ypwd.getText().toString();//获取输入的原密码
                String xpwd = et_xpwd.getText().toString();//获取输入的新密码
                String zxpwd = et_zxpwd.getText().toString();//获取第二次输入的新密码
                //对每个密码进行逻辑判断
                if(ypwd.equals("")){
                    Toast.makeText(SysSettingActivity.this, "请输入原始密码", Toast.LENGTH_SHORT).show();
                }else if(!ypwd.equalsIgnoreCase(pwd)){
                    Toast.makeText(SysSettingActivity.this, "输入的密码与原密码不一致", Toast.LENGTH_SHORT).show();
                }else if(xpwd.equals("")){
                    Toast.makeText(SysSettingActivity.this, "请输入新密码",Toast.LENGTH_SHORT).show();
                }else if(xpwd.equalsIgnoreCase(ypwd)){
                    Toast.makeText(SysSettingActivity.this, "所输入的新密码与原密码不能相同", Toast.LENGTH_SHORT).show();
                }else if(zxpwd.equals("")){
                    Toast.makeText(SysSettingActivity.this, "请再次输入新密码", Toast.LENGTH_SHORT).show();
                }else if(!zxpwd.equalsIgnoreCase(xpwd)){
                    Toast.makeText(SysSettingActivity.this, "两次输入的新密码不一致", Toast.LENGTH_SHORT).show();
                }else{
                    ContentValues values =new ContentValues();
                    values.put("pwd",xpwd);
                    db.update("tb_userinfo",values,"name=?",new
                            String[]{name});
                    Toast.makeText(SysSettingActivity.this, "密码修改成功",
                            Toast.LENGTH_SHORT).show();
                    Intent intent=new Intent(SysSettingActivity.this,
                            LoginActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
        });
    }
    //第五步:取消按钮功能-----------------------代码
    private void btncancel() {
        bt_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(SysSettingActivity.this,
                        MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

  1. 心得体会

在这次移动终端开发课程设计过程中,我发现平时学习的知识与实践环节所用到的有一定的差距,往往我觉得自己掌握的很好或者自认为熟练的技术却在此次实践环节中往往出问题,书本上的知识只提供方法的借鉴,实践中自己必须摸索出适合具体工作的方法,这一切都离不开钻研精神与勤学好问的精神.在人与人相处过程中我收获更大,首先要谦虚谨慎,不能自以为是,认为自己懂得很多,而仅仅埋头苦干,而不向他人请教,工作不但是实践与应用的过程,同时也是学习的过程,我们必须加强与他人的沟通学习,以便获得与他人的交流。在这短短的时间里,让我深深的感觉到自己在实际应用中所学专业知识的匮乏。让我真真领悟到“学无止境”这句话的涵义。而老师在专业认识周中所讲的,都是课本上没有而对我们又非常实用的东西,这又给我们的实训增加了浓墨淡采的光辉。我懂得了实际生活中,专业知识是怎样应用与实践的。

 

以下是遇到的问题:

一、空指针异常问题

  问题场景:

java

public class MainActivity extends AppCompatActivity {

    private TextView mTextView;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        // 忘记初始化 mTextView

        String text = mTextView.getText().toString();

        Log.d("MainActivity", text);

    }

}

在上面的代码中,`mTextView` 没有通过 `findViewById()` 方法进行初始化,就直接调用了 `getText()` 方法,这就会导致空指针异常。

  问题原因:访问了未初始化的对象的成员方法。

  问题影响:应用在运行时会崩溃,用户无法正常使用应用,并且在 Logcat 中会输出空指针异常的错误信息,影响开发人员对问题的排查和修复效率。

  解决方法:确保在使用对象之前对其进行正确初始化,即添加 `mTextView = findViewById(R.id.textView);` 这样的初始化代码。

二、异步任务线程泄漏问题

异步任务(AsyncTask)使用不当容易导致线程泄漏。

  问题场景:

java

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private MyAsyncTask mAsyncTask;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mAsyncTask = new MyAsyncTask();

        mAsyncTask.execute();

    }

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        @Override

        protected Void doInBackground(Void... voids) {

            try {

                Thread.sleep(5000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            return null;

        }

        @Override

        protected void onPostExecute(Void aVoid) {

            Log.d(TAG, "onPostExecute: " + this);

        }

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        // 此时 AsyncTask 可能还在后台运行

    }

}

 

 

在这个例子中,当 `MainActivity` 被销毁时,`MyAsyncTask` 可能还在后台运行,它仍然持有对 `MainActivity` 的引用(因为 `MyAsyncTask` `MainActivity` 的内部类),从而导致 `MainActivity` 无法被垃圾回收,出现线程泄漏。

  问题原因:异步任务对象持有了活动(Activity)的引用,并且异步任务的生命周期长于活动的生命周期。

  问题影响:占用过多的内存资源,导致应用内存泄漏,随着时间推移,可能会导致应用崩溃或者设备运行缓慢。

  解决方法:可以将异步任务的定义移到外部类中,或者使用静态内部类来定义异步任务,并且通过弱引用来持有外部类对象的引用,避免内部类持有外部类的强引用。同时,在活动的生命周期方法(如 `onDestroy()`)中取消异步任务。

三、资源文件访问错误问题

资源文件访问错误也是一个常见的编码问题。

  问题场景:

java

public class MainActivity extends AppCompatActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        // 错误的资源 ID

        String appName = getResources().getString(R.string.app_nam);

        TextView textView = findViewById(R.id.textView);

        textView.setText(appName);

    }

}

在上面的代码中,正确的资源 ID `R.string.app_name`,但错误地写成了 `R.string.app_nam`,导致无法正确获取字符串资源。

 

  问题原因:在访问资源文件时,资源 ID 拼写错误或者资源文件路径错误。

  问题影响:应用在运行时可能会出现资源找不到的异常,导致界面显示不正确或者功能无法正常使用,并且在 Logcat 中会输出资源找不到的错误信息,影响开发效率。

  解决方法:仔细检查资源 ID 的拼写是否正确,确保资源文件的路径正确,并且资源文件中确实存在对应的资源项。

 

posted @ 2025-05-20 15:10  痛苦代码源  阅读(24)  评论(0)    收藏  举报