需要源码或图片集请点赞关注收藏后评论区留言~~~
好用的记账本必须具备两项基本功能。一项时记录新帐单,另一项时查看账单列表,其中账单的记录操作要求用户输入账单的明细要素,包括账单的发生时间,账单的收支类型,账单的交易金额,账单的事由描述等等,账单通常分月展示,每页显示单个月份的账单数据,还要支持在不同月份之间切换,每月的账单数据按照时间从上往下排列,然后列表末尾展示当月的账单合计情况。
基本界面如下 用户可以自己输入类型,说明以及金额大小

除了文本视图,按钮,编辑框,单选按钮等简单控件之外,记账本还用到了下列控件以及相关的适配器 如果读者有疑问可以进我主页查看Android Studio专栏 里面有详细的讲解
翻页视图
翻页标签栏
碎片适配器
碎片
列表视图
基本适配器
提醒对话框
日期选择对话框
下面列出了活动页面开始直到账单行的依赖嵌套关系(账单总体页面->每个月份的账单页->每月账单的明细列表->每行的账单信息)

填写账单时间的时候,输入界面默认展示当天日期,用户若想修改账单时间,就要点击日期文本,此时界面弹出日期选择对话框,等待用户选择完具体日期,再回到主界面展示选定日期的文本
因为账单明细位于列表视图当中,且列表视图允许同时设置列表项的点击监听器和长按监听器,所以可考虑将列表项的点击监听器映射到账单的编辑功能。
保存账单记录之时,也要先判断数据库中是否已经存在对应账单,如果有找到对应的账单记录,那么执行记录更新操作,否则执行记录添加操作。
选择时间页面框

查询账单页面框

翻页视图

添加类代码
package com.example.chapter08;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter08.bean.BillInfo;
import com.example.chapter08.database.BillDBHelper;
import com.example.chapter08.util.DateUtil;
import com.example.chapter08.util.ViewUtil;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class BillAddActivity extends AppCompatActivity implements
RadioGroup.OnCheckedChangeListener, View.OnClickListener, DatePickerDialog.OnDateSetListener {
private final static String TAG = "BillAddActivity";
private TextView tv_date;
private RadioButton rb_income;
private RadioButton rb_expand;
private EditText et_desc;
private EditText et_amount;
private int mBillType = 1; // 账单类型。0 收入;1 支出
private int xuhao; // 如果序号有值,说明已存在该账单
private Calendar calendar = Calendar.getInstance(); // 获取日历实例,里面包含了当前的年月日
private BillDBHelper mBillHelper; // 声明一个账单数据库的帮助器对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bill_add);
TextView tv_title = findViewById(R.id.tv_title);
TextView tv_option = findViewById(R.id.tv_option);
tv_date = findViewById(R.id.tv_date);
RadioGroup rg_type = findViewById(R.id.rg_type);
rb_income = findViewById(R.id.rb_income);
rb_expand = findViewById(R.id.rb_expand);
et_desc = findViewById(R.id.et_desc);
et_amount = findViewById(R.id.et_amount);
tv_title.setText("请填写账单");
tv_option.setText("账单列表");
findViewById(R.id.iv_back).setOnClickListener(this);
tv_option.setOnClickListener(this);
tv_date.setOnClickListener(this);
findViewById(R.id.btn_save).setOnClickListener(this);
rg_type.setOnCheckedChangeListener(this);
}
@Override
protected void onResume() {
super.onResume();
xuhao = getIntent().getIntExtra("xuhao", -1);
mBillHelper = BillDBHelper.getInstance(this); // 获取账单数据库的帮助器对象
if (xuhao != -1) { // 序号有值,就展示数据库里的账单详情
List<BillInfo> bill_list = (List<BillInfo>) mBillHelper.queryById(xuhao);
if (bill_list.size() > 0) { // 已存在该账单
BillInfo bill = bill_list.get(0); // 获取账单信息
Date date = DateUtil.formatString(bill.date);
Log.d(TAG, "bill.date="+bill.date);
Log.d(TAG, "year="+date.getYear()+",month="+date.getMonth()+",day="+date.getDate());
calendar.set(Calendar.YEAR, date.getYear()+1900);
calendar.set(Calendar.MONTH, date.getMonth());
calendar.set(Calendar.DAY_OF_MONTH, date.getDate());
if (bill.type == 0) { // 收入
rb_income.setChecked(true);
} else { // 支出
rb_expand.setChecked(true);
}
et_desc.setText(bill.desc); // 设置账单的描述文本
et_amount.setText(""+bill.amount); // 设置账单的交易金额
}
}
tv_date.setText(DateUtil.getDate(calendar)); // 设置账单的发生时间
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_back) {
finish(); // 关闭当前页面
} else if (v.getId() == R.id.tv_option) {
Intent intent = new Intent(this, BillPagerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志
startActivity(intent); // 跳到账单列表页面
} else if (v.getId() == R.id.tv_date) {
// 构建一个日期对话框,该对话框已经集成了日期选择器。
// DatePickerDialog的第二个构造参数指定了日期监听器
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) {
saveBill(); // 保存账单
}
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
mBillType = (checkedId==R.id.rb_expand) ? 1 : 0;
}
@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));
}
// 保存账单
private void saveBill() {
//ViewUtil.hideAllInputMethod(this); // 隐藏输入法软键盘
ViewUtil.hideOneInputMethod(this, et_amount); // 隐藏输入法软键盘
BillInfo bill = new BillInfo();
bill.xuhao = xuhao;
bill.date = tv_date.getText().toString();
bill.month = 100*calendar.get(Calendar.YEAR) + (calendar.get(Calendar.MONTH)+1);
bill.type = mBillType;
bill.desc = et_desc.getText().toString();
bill.amount = Double.parseDouble(et_amount.getText().toString());
mBillHelper.save(bill); // 把账单信息保存到数据库
Toast.makeText(this, "已添加账单", Toast.LENGTH_SHORT).show();
resetPage(); // 重置页面
}
// 重置页面
private void resetPage() {
calendar = Calendar.getInstance();
et_desc.setText("");
et_amount.setText("");
tv_date.setText(DateUtil.getDate(calendar));
}
}
查看类代码
package com.example.chapter08;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.DatePicker;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerTabStrip;
import androidx.viewpager.widget.ViewPager;
import com.example.chapter08.adapter.BillPagerAdpater;
import com.example.chapter08.util.DateUtil;
import java.util.Calendar;
public class BillPagerActivity extends AppCompatActivity implements
View.OnClickListener, DatePickerDialog.OnDateSetListener, ViewPager.OnPageChangeListener {
private TextView tv_month;
private ViewPager vp_bill; // 声明一个翻页视图对象
private Calendar calendar = Calendar.getInstance(); // 获取日历实例,里面包含了当前的年月日
@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_option = findViewById(R.id.tv_option);
tv_month = findViewById(R.id.tv_month);
tv_title.setText("账单列表");
tv_option.setText("添加账单");
findViewById(R.id.iv_back).setOnClickListener(this);
tv_option.setOnClickListener(this);
tv_month.setOnClickListener(this);
tv_month.setText(DateUtil.getMonth(calendar));
// 从布局视图中获取名叫vp_bill的翻页视图
vp_bill = findViewById(R.id.vp_bill);
initViewPager(); // 初始化翻页视图
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_back) {
finish(); // 关闭当前页面
} else if (v.getId() == R.id.tv_option) {
Intent intent = new Intent(this, BillAddActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志
startActivity(intent); // 跳到账单填写页面
} else if (v.getId() == R.id.tv_month) {
// 构建一个日期对话框,该对话框已经集成了日期选择器。
// DatePickerDialog的第二个构造参数指定了日期监听器
DatePickerDialog dialog = new DatePickerDialog(this, this,
calendar.get(Calendar.YEAR), // 年份
calendar.get(Calendar.MONTH), // 月份
calendar.get(Calendar.DAY_OF_MONTH)); // 日子
dialog.show(); // 显示日期选择对话框
}
}
@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(month); // 设置翻页视图显示第几页
}
// 初始化翻页视图
private void initViewPager() {
// 从布局视图中获取名叫pts_bill的翻页标签栏
PagerTabStrip pts_bill = findViewById(R.id.pts_bill);
// 设置翻页标签栏的文本大小
pts_bill.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);
// 构建一个商品图片的翻页适配器
BillPagerAdpater adapter = new BillPagerAdpater(getSupportFragmentManager(), calendar.get(Calendar.YEAR));
vp_bill.setAdapter(adapter); // 设置翻页视图的适配器
vp_bill.setCurrentItem(calendar.get(Calendar.MONTH)); // 设置翻页视图显示第几页
vp_bill.addOnPageChangeListener(this); // 给翻页视图添加页面变更监听器
}
// 翻页状态改变时触发
public void onPageScrollStateChanged(int state) {}
// 在翻页过程中触发
public void onPageScrolled(int position, float ratio, int offset) {}
// 在翻页结束后触发
public void onPageSelected(int position) {
calendar.set(Calendar.MONTH, position);
tv_month.setText(DateUtil.getMonth(calendar));
}
}
适配器代码
package com.example.chapter08.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.chapter08.BillAddActivity;
import com.example.chapter08.R;
import com.example.chapter08.bean.BillInfo;
import com.example.chapter08.database.BillDBHelper;
import java.util.ArrayList;
import java.util.List;
public class BillListAdapter extends BaseAdapter implements AdapterView.OnItemClickListener,
AdapterView.OnItemLongClickListener{
private static final String TAG = "BillListAdapter";
private Context mContext; // 声明一个上下文对象
private List<BillInfo> mBillList = new ArrayList<BillInfo>(); // 账单信息列表
public BillListAdapter(Context context, List<BillInfo> billList) {
mContext = context;
mBillList = billList;
}
@Override
public int getCount() {
return mBillList.size();
}
@Override
public Object getItem(int position) {
return mBillList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
// 根据布局文件item_bill.xml生成转换视图对象
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_bill, null);
holder.tv_date = convertView.findViewById(R.id.tv_date);
holder.tv_desc = convertView.findViewById(R.id.tv_desc);
holder.tv_amount = convertView.findViewById(R.id.tv_amount);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
BillInfo bill = mBillList.get(position);
holder.tv_date.setText(bill.date);
holder.tv_desc.setText(bill.desc);
if (bill.date.equals("合计")) {
holder.tv_amount.setText(bill.remark);
} else {
holder.tv_amount.setText(String.format("%s%d元", bill.type==0?"收入":"支出", (int) bill.amount));
}
return convertView;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position >= mBillList.size()-1) { // 合计行不响应点击事件
return;
}
Log.d(TAG, "onItemClick position=" + position);
BillInfo bill = mBillList.get(position);
// 以下跳转到账单填写页面
Intent intent = new Intent(mContext, BillAddActivity.class);
intent.putExtra("xuhao", bill.xuhao); // 携带账单序号,表示已存在该账单
mContext.startActivity(intent); // 因为已存在该账单,所以跳过去实际会编辑账单
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
if (position >= mBillList.size()-1) { // 合计行不响应长按事件
return true;
}
Log.d(TAG, "onItemLongClick position=" + position);
BillInfo bill = mBillList.get(position); // 获得当前位置的账单信息
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
String desc = String.format("是否删除以下账单?\n%s %s%d %s", bill.date,
bill.type==0?"收入":"支出", (int) bill.amount, bill.desc);
builder.setMessage(desc); // 设置提醒对话框的消息文本
builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
deleteBill(position); // 删除该账单
}
});
builder.setNegativeButton("否", null);
builder.create().show(); // 显示提醒对话框
return true;
}
// 删除该账单
private void deleteBill(int position) {
BillInfo bill = mBillList.get(position);
mBillList.remove(position);
notifyDataSetChanged(); // 通知适配器发生了数据变化
// 获得数据库帮助器的实例
BillDBHelper helper = BillDBHelper.getInstance(mContext);
helper.delete(bill.xuhao); // 从数据库删除指定序号的账单
}
public final class ViewHolder {
public TextView tv_date;
public TextView tv_desc;
public TextView tv_amount;
}
}
添加
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/title_booking" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:text="账单日期:"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_date"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:drawableRight="@drawable/arrow_down"
android:gravity="center"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
<RadioGroup
android:id="@+id/rg_type"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_margin="5dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:text="账单类型:"
android:textColor="@color/black"
android:textSize="17sp" />
<RadioButton
android:id="@+id/rb_income"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left|center"
android:checked="false"
android:text="收入"
android:textColor="#000000"
android:textSize="17sp" />
<RadioButton
android:id="@+id/rb_expand"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left|center"
android:checked="true"
android:text="支出"
android:textColor="#000000"
android:textSize="17sp" />
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:text="事项说明:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_desc"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:gravity="left|top"
android:background="@drawable/editext_selector"
android:textColor="@color/black"
android:textSize="17sp"
android:hint="请填写说明内容" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:text=" 金额:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_amount"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/editext_selector"
android:inputType="number"
android:textColor="@color/black"
android:textSize="17sp"
android:hint="单位(元)" />
</LinearLayout>
<Button
android:id="@+id/btn_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="保 存"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
查看
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/title_booking" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:gravity="center|top"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:text="请选择月份:"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_month"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:drawableRight="@drawable/arrow_down"
android:gravity="center"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_bill"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.PagerTabStrip
android:id="@+id/pts_bill"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
</LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame