Android内存管理知识点
Android内存管理知识点 问题 1: 什么是垃圾回收机制? 解答: 垃圾回收(GC)是由Java虚拟机(JVM)垃圾回收器提供的一种对内存回收的机制。它会在内存空间不足或者内存占用过高的时候,自动回收那些没有引用的对象,以释放内存资源。垃圾回收的主要目标是自动管理内存,避免内存泄漏和内存溢出。 ...
Android内存管理知识点 问题 1: 什么是垃圾回收机制? 解答: 垃圾回收(GC)是由Java虚拟机(JVM)垃圾回收器提供的一种对内存回收的机制。它会在内存空间不足或者内存占用过高的时候,自动回收那些没有引用的对象,以释放内存资源。垃圾回收的主要目标是自动管理内存,避免内存泄漏和内存溢出。 ...
Android(6) 记账本小项目 BillPagerActivity.java package com.showguan.chapter08; import android.app.DatePickerDialog; import android.content.Intent; import android.media.Image; import android.os.Bundle; import android.util.TypedValue; import android.view.View; import android.widget.DatePicker; import android.widget.ImageView; import android.widget.TextView; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.viewpager.widget.PagerTabStrip; import androidx.viewpager.widget.ViewPager; import com.showguan.chapter08.adapter.BillPagerAdapter; import com.showguan.chapter08.database.BillDBHelper; import com.showguan.chapter08.util.DateUtil; import org.w3c.dom.Text; import java.util.Calendar; public class BillPagerActivity extends AppCompatActivity implements View.OnClickListener, DatePickerDialog.OnDateSetListener { private Calendar calendar; private TextView tv_month; private ViewPager vp_bill; private BillDBHelper mDBhelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bill_pager); TextView tv_title = findViewById(R.id.tv_title); TextView tv_subtitle = findViewById(R.id.tv_subtitle); ImageView iv_back = findViewById(R.id.iv_back); iv_back.setOnClickListener(this); tv_month = findViewById(R.id.tv_month); tv_title.setText("账单列表"); tv_subtitle.setText("添加账单"); tv_subtitle.setOnClickListener(this); calendar = Calendar.getInstance(); tv_month.setText(DateUtil.getMonth(calendar)); tv_month.setOnClickListener(this); mDBhelper = BillDBHelper.getInstance(this); mDBhelper.openReadLink(); mDBhelper.openWriteLink(); initViewPager(); } // 初始化ViewPager private void initViewPager() { PagerTabStrip pts_bill = findViewById(R.id.pts_bill); pts_bill.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17); vp_bill = findViewById(R.id.vp_bill); BillPagerAdapter adapter = new BillPagerAdapter(getSupportFragmentManager(), calendar.get(Calendar.YEAR)); vp_bill.setAdapter(adapter); vp_bill.setCurrentItem(calendar.get(Calendar.MONTH)); } @Override public void onClick(View v) { if(v.getId() == R.id.tv_month){ DatePickerDialog dialog = new DatePickerDialog(this, this, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) ); dialog.show(); } else if (v.getId() == R.id.tv_subtitle) { Intent intent = new Intent(this, BillAddActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); } else if (v.getId() == R.id.iv_back) { finish(); } } @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); tv_month.setText(DateUtil.getMonth(calendar)); vp_bill.setCurrentItem(calendar.get(Calendar.MONTH)); } @Override public void onPointerCaptureChanged(boolean hasCapture) { super.onPointerCaptureChanged(hasCapture); } @Override protected void onDestroy() { super.onDestroy(); mDBhelper.closeLink(); } } BillAddActivity.java package com.showguan.chapter08; import android.app.DatePickerDialog; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.ImageView; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import com.showguan.chapter08.database.BillDBHelper; import com.showguan.chapter08.entity.BillInfo; import com.showguan.chapter08.util.DateUtil; import com.showguan.chapter08.util.ToastUtil; import java.util.Calendar; import java.util.Date; public class BillAddActivity extends AppCompatActivity implements View.OnClickListener, DatePickerDialog.OnDateSetListener { private static final String TAG = "Kennem"; private TextView tv_date; private Calendar calendar; private TextView tv_subtitle; private TextView tv_title; private RadioButton rb_in; private RadioButton rb_out; private EditText et_remark; private EditText et_amount; private Button btn_save; private RadioGroup rg_type; private BillDBHelper mDBhelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bill_add); tv_title = findViewById(R.id.tv_title); tv_subtitle = findViewById(R.id.tv_subtitle); rg_type = findViewById(R.id.rg_type); rb_in = findViewById(R.id.rb_in); rb_out = findViewById(R.id.rb_out); et_remark = findViewById(R.id.et_remark); et_amount = findViewById(R.id.et_amount); btn_save = findViewById(R.id.btn_save); ImageView iv_back = findViewById(R.id.iv_back); iv_back.setOnClickListener(this); tv_title.setText("请记录账单"); tv_subtitle.setText("账单列表"); tv_subtitle.setOnClickListener(this); tv_date = findViewById(R.id.tv_date); calendar = Calendar.getInstance(); tv_date.setText(DateUtil.getDate(calendar)); tv_date.setOnClickListener(this); btn_save.setOnClickListener(this); mDBhelper = BillDBHelper.getInstance(this); mDBhelper.openReadLink(); mDBhelper.openWriteLink(); } @Override public void onClick(View v) { if (v.getId() == R.id.tv_date) { DatePickerDialog dialog = new DatePickerDialog(this, this, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) ); dialog.show(); } else if (v.getId() == R.id.btn_save) { BillInfo bill = new BillInfo(); bill.date = tv_date.getText().toString(); bill.type = rg_type.getCheckedRadioButtonId() == R.id.rb_in ? BillInfo.BILL_TYPE_INCOME : BillInfo.BILL_TYPE_COSE; bill.remark = et_remark.getText().toString(); bill.amount = Double.parseDouble(et_amount.getText().toString()); Log.d(TAG, bill.toString()); if (mDBhelper.save(bill) > 0) { ToastUtil.show(this, "添加账单成功"); } } else if (v.getId() == R.id.iv_back) { finish(); } else if (v.getId() == R.id.tv_subtitle) { Intent intent = new Intent(this, BillPagerActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } } @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); tv_date.setText(DateUtil.getDate(calendar)); } @Override protected void onDestroy() { super.onDestroy(); } } BillPagerAdapter.java package com.showguan.chapter08.adapter; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import com.showguan.chapter08.fragment.BillFragment; public class BillPagerAdapter extends FragmentPagerAdapter { private final int mYear; private static final String TAG = "Kennem"; public BillPagerAdapter(@NonNull FragmentManager fm, int year) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); this.mYear = year; } @NonNull @Override public Fragment getItem(int position) { Log.d(TAG, String.valueOf(position)); int month = position + 1; String zeroMonth = month < 10 ? "0" + month : "" + month; String yearMonth = mYear + "-" + zeroMonth; Log.d(TAG, yearMonth); return BillFragment.newInstance(yearMonth); } @Override public int getCount() { return 12; } @Nullable @Override public CharSequence getPageTitle(int position) { return (position + 1) + "月份"; } } BillListAdapter.java package com.showguan.chapter08.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.showguan.chapter08.R; import com.showguan.chapter08.entity.BillInfo; import java.util.List; public class BillListAdapter extends BaseAdapter { private final List<BillInfo> mBillInfoList; private final Context mContext; public BillListAdapter(Context context, List<BillInfo> billInfoList) { this.mContext = context; this.mBillInfoList = billInfoList; } @Override public int getCount() { return mBillInfoList.size(); } @Override public Object getItem(int position) { return mBillInfoList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if(convertView == null){ viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_bill, null); viewHolder.tv_date = convertView.findViewById(R.id.tv_date); viewHolder.tv_remark = convertView.findViewById(R.id.tv_remark); viewHolder.tv_amount = convertView.findViewById(R.id.tv_amount); convertView.setTag(viewHolder); }else{ viewHolder = (ViewHolder) convertView.getTag(); } BillInfo billInfo = mBillInfoList.get(position); viewHolder.tv_date.setText(billInfo.date); viewHolder.tv_remark.setText(billInfo.remark); viewHolder.tv_amount.setText(String.format("%s %d 元", billInfo.type == 0 ? "+" : "-" ,(int)billInfo.amount)); return convertView; } public final class ViewHolder{ public TextView tv_date; public TextView tv_remark; public TextView tv_amount; } } BillDBHelper.java package com.showguan.chapter08.database; import android.annotation.SuppressLint; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import androidx.annotation.Nullable; import com.showguan.chapter08.entity.BillInfo; import java.util.ArrayList; import java.util.List; public class BillDBHelper extends SQLiteOpenHelper { private static String TAG = "Kennem"; private static final String DB_NAME = "bill.db"; private static final String TABLE_BILL_INFO = "bill_info"; private static final int DB_VERSION = 2; private static BillDBHelper mHelper = null; private SQLiteDatabase mRDB = null; private SQLiteDatabase mWDB = null; private BillDBHelper(@Nullable Context context) { super(context, DB_NAME, null, DB_VERSION); } public static BillDBHelper getInstance(Context context) { if (mHelper == null) { mHelper = new BillDBHelper(context); } return mHelper; } public SQLiteDatabase openReadLink() { if (mRDB == null || !mRDB.isOpen()) { mRDB = mHelper.getReadableDatabase(); } return mRDB; } public SQLiteDatabase openWriteLink() { if (mWDB == null || !mWDB.isOpen()) { mWDB = mHelper.getReadableDatabase(); } return mWDB; } public void closeLink() { if (mRDB != null && mRDB.isOpen()) { mRDB.close(); mRDB = null; } if (mWDB != null && mWDB.isOpen()) { mWDB.close(); mWDB = null; } } @Override public void onCreate(SQLiteDatabase db) { //_id 保证id不是不是关键字 String sql = null; sql = "CREATE TABLE IF NOT EXISTS " + TABLE_BILL_INFO + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + " date VARCHAR NOT NULL," + " type VARCHAR NOT NULL," + " amount DOUBLE NOT NULL," + " remark VARCHAR NOT NULL);"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public long save(BillInfo billInfo) { ContentValues cv = new ContentValues(); cv.put("date", billInfo.date); cv.put("type", billInfo.type); cv.put("amount", billInfo.amount); cv.put("remark", billInfo.remark); return mWDB.insert(TABLE_BILL_INFO, null, cv); } @SuppressLint("Range") public List<BillInfo> queryByMonth(String yearMonth){ List<BillInfo> list = new ArrayList<>(); String sql = "select * from " + TABLE_BILL_INFO + " where date like '" + yearMonth + "%';"; Log.d(TAG, sql); Cursor cursor = mRDB.rawQuery(sql, null); while(cursor.moveToNext()){ BillInfo bill = new BillInfo(); bill.id = cursor.getInt(cursor.getColumnIndex("_id")); bill.date = cursor.getString(cursor.getColumnIndex("date")); bill.type = cursor.getInt(cursor.getColumnIndex("type")); bill.amount = cursor.getDouble(cursor.getColumnIndex("amount")); bill.remark = cursor.getString(cursor.getColumnIndex("remark")); Log.d(TAG, bill.toString()); list.add(bill); } return list; } } BillInfo.java package com.showguan.chapter08.entity; public class BillInfo { public int id; public String date; public int type; public double amount; public String remark; public static final int BILL_TYPE_INCOME = 0; public static final int BILL_TYPE_COSE = 1; @Override public String toString() { return "BillInfo{" + "id=" + id + ", date='" + date + '\'' + ", type=" + type + ", amount=" + amount + ", remark='" + remark + '\'' + '}'; } } BillFragment.java package com.showguan.chapter08.fragment; import android.os.Bundle; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import com.showguan.chapter08.R; import com.showguan.chapter08.adapter.BillListAdapter; import com.showguan.chapter08.database.BillDBHelper; import com.showguan.chapter08.entity.BillInfo; import java.util.List; public class BillFragment extends Fragment { public BillFragment() { } public static BillFragment newInstance(String yearMonth) { BillFragment fragment = new BillFragment(); Bundle args = new Bundle(); args.putString("yearMonth", yearMonth); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_bill, container, false); ListView lv_bill = view.findViewById(R.id.lv_bill); BillDBHelper mDBHelper = BillDBHelper.getInstance(getContext()); Bundle arguments = getArguments(); String yearMonth = arguments.getString("yearMonth"); List<BillInfo> billInfoList = mDBHelper.queryByMonth(yearMonth); BillListAdapter adapter = new BillListAdapter(getContext(), billInfoList); lv_bill.setAdapter(adapter); return view; } } 广播 广播的收发过程分为三个步骤: 发送标准广播 定义广播接收器 开关广播接收器 有序广播 ...
Android(5) 高级控件 SpinnerDialog + ArrayAdapter XML <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SpinnerDropdownActivity" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下拉模式的列表框" android:textSize="17sp"/> <Spinner android:id="@id/sp_dialog" android:layout_width="match_parent" android:layout_height="wrap_content" android:spinnerMode="dialog"/> </LinearLayout> item_select.xml <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:textColor="#0000ff" android:textSize="17sp" tools:text="火星"> </TextView> Java package com.showguan.chapter08; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import androidx.appcompat.app.AppCompatActivity; import com.showguan.chapter08.util.ToastUtil; public class SpinnerDialogActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { private Spinner sp_dialog; private static final String[] starArray = new String[]{ "水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_spinner_dialog); sp_dialog = findViewById(R.id.sp_dialog); ArrayAdapter<String> starAdapter = new ArrayAdapter<>(this, R.layout.item_select, starArray); sp_dialog.setPrompt("🌤选择行星"); sp_dialog.setAdapter(starAdapter); sp_dialog.setSelection(0); sp_dialog.setOnItemSelectedListener(this); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { ToastUtil.show(this, "您选择了: " + starArray[position]); } @Override public void onNothingSelected(AdapterView<?> parent) { } } SpinnerDropdown ...
《数字图像处理》课程综合项目——基于多种滤波器的图像去噪算法比较与分析 GUI界面: 本项目源代码和报告均已开源: 开源仓库:https://github.com/Kennems/Image_Processing_GUI 项目简介 本项目旨在设计一个基于Matlab的图像去噪GUI系统,通过应用多种图像去噪算法,提高图像的质量和可用性。该系统集成了多种经典和现代的去噪方法,并提供了直观的用户界面,方便用户对图像进行去噪处理和效果评估。 ...
Android(4) 就算是最低的15x15都已经不错了,以后还有时间去学,上了研究生也没人能保证你有15x15的收入 内容提供者(ContentProvider) CountentProvider为App存取内部数据提供统一的外部接口,让不同的应用之间得以共享数据 ...
Android(3) 清楚自己是在为了什么而努力,以后能得到什么,你想要什么结果。 数据存储 共享参数的用法 SharedPreferences 是 Android的一个轻量级存储工具,采用的存储结构是key-value的键值对方式 共享参数的存储介质是符合XML规范的配置文件。保存路径是:/data/data/应用包名/shared_prefs/文件名.xml 共享参数主要适用的场合: ...
Android(2) Activity的启动和结束 从当前页面跳转到新页面,跳转代码如下: startActivity(new Intent(源页面.this, 目标页面.class)) 从当前页面回到上一个页面,相当于关闭当前页面,返回代码如下: ...
Android(1) 【金山文档 | WPS云文档】 Kotlin 讲义 https://kdocs.cn/l/cu14rrCtfKxv 【金山文档 | WPS云文档】 Android 四大组件课程概要 https://kdocs.cn/l/croaFl0RS5LA 【金山文档 | WPS云文档】 Fragment 重点知识 https://kdocs.cn/l/cj89XRLXypb8 【金山文档 | WPS云文档】 Android UI 课程重点知识 https://kdocs.cn/l/cokrSwEg1GF4 【金山文档 | WPS云文档】 Android布局与优化 https://kdocs.cn/l/ciwSdaSLRAwB 【金山文档 | WPS云文档】 组件库 https://kdocs.cn/l/cvsBNce6AfjI 【金山文档 | WPS云文档】 Android 动画 https://kdocs.cn/l/cf4bQiAeZdlI 【金山文档 | WPS云文档】 自定义控件的实现 https://kdocs.cn/l/cu3bUFFJVvn8 【金山文档 | WPS云文档】 权限与网络请求课程预习 https://kdocs.cn/l/cme7bRkDMYcB 【金山文档 | WPS云文档】 内存泄漏和ANR预习 https://kdocs.cn/l/cpFLi1gGV4Xs Android 开发环境配置:https://www.kdocs.cn/l/cekCbJzGOsTM Git 环境配置:https://kdocs.cn/l/crWdNGh7Onio ctrl + alt + o 自动组织导入 ...
Java Web开发(7) Spring原理 配置优先级 SpringBoot中支持三种格式配置文件的优先级 properties yaml yml 配置 SpringBoot除了支持配置文件属性配置,还支持Java系统属性和命令行参数的方式进行属性配置 ...
面经(1) 八股分为:基础知识,底层原理,场景应用 基础知识:javaguide, 死记硬背,思维导图 底层原理:八股合集,面经+GPT+整理 场景应用:面经+积累 20240611 面向面经背八股,小米面经 ...
Java Web开发(6) 事务:事务是一组操作的集合,它是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败 start transaction / begin commit rollback Spring事务管理 @Transactional 位置:业务(service)层的方法上、类上、接口上 作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务。 事务属性 ...
LeetCode双周赛132 & 周赛401(240608/09) 3181. 执行操作可获得的最大总奖励 II周赛第四题 题目大意 给定一个整数数组 rewardValues,长度为 n,表示不同位置的奖励值。初始时,总奖励 x 为 0,所有下标都是未标记的。可以执行以下操作任意次: ...
Java Web开发(5) MyBatis MyBatis是一款优秀的持久层框架,用于简化JDBC的开发。 使用Mybatis查询所有用户数据 创建SpringBoot工程, 数据库表user, 实体类User ...
双周赛131(240525) AK的第二场😝, 第四题是用C++ 找网上模板,套用查找最长的连0串过的, 最后两分钟才过,很惊险。赛后发现做法并不优秀,但是不需要平衡树。 3161. 物块放置查询 题目大意: ...
周赛399(240526) 这场掉分了,第四题没思路,而且罚时太多了😥 第三题3164. 优质数对的总数 II 题目大意: 给定两个整数数组nums1和nums2,以及一个正整数k。如果nums1[i]可以被nums2[j]*k整除,则称数对(i, j)为优质数对。要求计算优质数对的总数。 ...