当前位置: 首页 > news >正文

安卓开发学习记录(持续学习)

文章目录

  • 前言
  • 工具
  • 创建项目
  • 简单控件即UI
    • 一、界面显示与逻辑处理
    • 二、文本
    • 三、布局
  • 四、按钮
  • 五、控件综合训练(简易计算器)
  • 六、Activity
  • 七. 中级控件


前言

最近在有在持续学习Java的安卓开发,不断的把知识记录下。


工具

  1. Android Studio安装
    [Studio安装][1]
    [1]: https://developer.android.google.cn/studio “Studio安装”

file

  1. SDK下载
    SDK即软件开发工具包,可将App源码编译成可执行的App应用

file

创建项目

  1. 创建项目
    file

file

这里Minimum SDK后面指的是兼容到安卓几,表示你的应用支持的最低版本,看百分比选,一般目前的都是9.0-10.0。

  1. 内置模拟器
    file

初始化Gradle要下载半小时,内置模拟器也有十多G,默认在C盘很不爽,可以移动,

file

注册环境变量,然后修改下面的配置,直接把目录移动到想存的位置即可。
file

  1. 观察App运行日志
    Android采用Log日志打印日志,各类日志划分:

Log.e 表示错误信息,可能导致程序崩溃
Log.w:表示警告信息
Log.i:表示一般消息
Log.d:表示调试信息,可把程序运行变量值打印,方便跟踪调试
Log.v:表示冗余信息

  1. 真机调试

1、使用数据库连接到电脑
2、电脑上会自动安装USB存储设备驱动
3、打开手机的开发者选项并开启USB调试
4、将连接的手机设备文件传输模式,并允许计算机进行USB调试

  1. 关于安卓开发语言
    App开发分为两大技术路线,分别为原生开发和混合开发,官方的编程语言包括Java和Kotlin。
    混合开发渲染性能没有原生开发好,但是混合开发可以跨平台,版本更新不需要重新下载API文件。
    关于C和C++,Java是解释型语言,在处理图像和音视频时性能显然就有瓶颈,而C和C++是编译型语言,会
    先翻译成机器语言,在图像和音视频处理时可以调用java的JNI接口调用C和C++程序进行处理,也称NDK。

  2. 目录结构
    file

mainfests:App运行配置文件
java子目录:存放java源代码,后面两个包存放测试用的代码

res目录下:
drawable:存放图形描述和图片文件
Layout:App页面的布局文件
mipmap:App的启动图标
values:存放常量的文件,如样式风格等

Gradle Scripts目录下:
build.gradle:描述项目级和模块级的App工程编译规则
proguard-rules.pro:java代码的混淆规则,保证安全性
gradle.properties:用于编译工程的命令行参数
local.properties:本地配置文件,描述开发者电脑的环境配置
settings.gradle:配置了需要编译的模块

  1. build.gradle的文件概述解释
plugins {//使用的插件id 'com.android.application'
}android {namespace 'com.example.myapplication'compileSdk 33 //编译使用的SDK版本号,33表示使用Android13defaultConfig {// App的包名applicationId "com.example.myapplication"//指定App适合运行的最小的SDK版本号,28表示最小在Android9上运行minSdk 28//目标设备的版本号,表示App最希望在那个版本的Android上运行targetSdk 33//App的应用版本号versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}//跟单元测试相关buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}
//指定App编译的依赖包信息
dependencies {//指定编译的Android高版本支持库implementation 'androidx.appcompat:appcompat:1.4.1'implementation 'com.google.android.material:material:1.5.0'implementation 'androidx.constraintlayout:constraintlayout:2.1.3'//指定单元测试编译用的junit版本号testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.3'androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
  1. 清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

android:icon:App手机屏幕显示的图标
android:label:App手机屏幕显示的名称
android:allowBackup:是否允许数据备份,数据丢失时恢复应用
android:theme:指定App显示的风格
android:supportsRtl:是否支持波斯语等从右向左的文字排列顺序语言

activity应用程序组件,提供屏幕,用来交互完成某项任务
android:exported:当前Activity是否可以被另一个Application的组件启动
android:name:启动应用首先启动那个Applicaiton

简单控件即UI

一、界面显示与逻辑处理

  1. 创建新的activity页面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/text2" /></LinearLayout>
  1. 创建新的MainActivity类,并将类加入Mainifest
package com.example.myapplication;import android.os.Bundle;import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity2 extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);}
}

<activity android:name=".MainActivity2"/>

  1. 设置跳转按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"/><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="跳转"/></LinearLayout>
  1. 写跳转方法
package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv=findViewById(R.id.tv);tv.setText("你好,世界!");Button button=findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent=new Intent();intent.setClass(MainActivity.this,MainActivity2.class);startActivity(intent);}});}
}

file

二、文本

  1. 文本大小

px :图像元素,跟随屏幕大小和像素数量关系变化。
resolution:屏幕垂直和水平方向的像素数量。
dpi:像素密度,指屏幕上每英寸距离中有多少个像素点。
Density:指定每平方英寸含有的像素点数量。
dip/dp:长度单位,同一个单位在不同设备中有不同显示效果。
sp:专门用于设置字体,大小会根据系统的字体大小改变而改变。
dip是开发中的长度单位,最后也要转换为px,px=dip*dpi/160

例:如 320*480分辨率 3.6寸的手机:
dpi=(3202+4802)^(1/2)/3.6=160 所以 1dp=1px
对于相同尺寸的手机,即使分辨率不同,占用屏幕比例也相同

  1. 设置文本颜色

设置文本的颜色一般可直接设置,也可以通过十六进制设置,如0xFFFFEEDD, 其中先
后十六进制顺序为透明度,红色,绿色,蓝色。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/text_color"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="直接设置文本颜色" /><TextViewandroid:id="@+id/text_hex_color"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:textColor="@color/purple_200"android:text="十六进制设置文本颜色"/><TextViewandroid:id="@+id/text_code_color"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="代码中设置文本颜色"/><TextViewandroid:id="@+id/text_background"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="设置文本背景颜色"android:background="#ff00ff00"/></LinearLayout>
public class MainTextActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_text);TextView text_color=findViewById(R.id.text_color);text_color.setTextColor(Color.GREEN);TextView text_code_color=findViewById(R.id.text_code_color);text_code_color.setTextColor(0xff00ff00);}
}
  1. 视图

wrap_content:自适应大小,刚好能包含内容
match_parent:当前控件的大小和父布局的大小一样
dp:自行设置dp大小

在代码中设置视图宽高。
调用控件对象getLayoutParams方法获取控件的布局参数。
调用控件对象的setLayoutParams方法,填入修改后布局参数使之生效。

public class ViewBorderActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_view_border);TextView text_borer=findViewById(R.id.text_view_border);ViewGroup.LayoutParams params=text_borer.getLayoutParams();params.width= Utils.dip2px(this,300);text_borer.setLayoutParams(params);}
}public class Utils {//根据分辨率dp转化为像素pxpublic static int dip2px(Context context, float dpValue){//获取当前像素密度,1个dp对应多少个像素float scale=context.getResources().getDisplayMetrics().density;return (int)(dpValue*scale+0.5f);}
}

三、布局

  1. 线性布局LinearLayout

orientation为horizontal,内部视图水平方向排列
oritentation为vertical,内部视图竖着排列

  1. 相对布局RelativeLayout

相对布局的下级视图位置由其他视图决定,确定位置参照物分两种:
(1)与该视图自身评级的视图
(2)该视图的上级视图
不设定,默认在左上角

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="#ffffff"android:text="我在中间"android:textColor="#000000"android:textSize="10sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:background="#ffffff"android:text="我在上级左边中间"android:textColor="#000000"android:textSize="10sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#ffffff"android:layout_alignParentBottom="true"android:text="我在上级底部对齐"android:textSize="10sp"android:textColor="#000000"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@id/center"android:layout_alignTop="@id/center"android:background="#ffffff"android:text="我在中间左边"android:textColor="#000000"android:textSize="10sp" />
</RelativeLayout>
  1. 网格布局GridLayout,支持多行多列的表格排列

网格布局默认从左往右,从上到下,属性如下
columnCount,指定网格列数,即每行能放多少视图
rowCount,指定网格行数,每列能放多少个视图

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:columnCount="2"android:rowCount="2"><TextViewandroid:layout_width="0dp"android:layout_columnWeight="1"android:layout_height="60dp"android:text="红色"android:background="#ff0000"android:textSize="20sp"android:gravity="center"android:textColor="#000000"/><TextViewandroid:layout_width="0dp"android:layout_columnWeight="1"android:layout_height="60dp"android:text="橙色"android:background="#ffaa00"android:textSize="20sp"android:gravity="center"android:textColor="#000000"/><TextViewandroid:layout_width="0dp"android:layout_columnWeight="1"android:layout_height="60dp"android:text="绿色"android:background="#00ff00"android:textSize="20sp"android:gravity="center"android:textColor="#000000"/><TextViewandroid:layout_width="0dp"android:layout_columnWeight="1"android:layout_height="60dp"android:text="紫色"android:background="#660066"android:textSize="20sp"android:gravity="center"android:textColor="#000000"/></GridLayout>
  1. 滚动视图ScrollView

ScrollView,垂直方向滚动,垂直方向滚动时,layout_width属性值设置为math_parent,layout_height属性设置为wrap_content
HorizontalScrollView,水平方向滚动,layout_width属性值设置为wrap_content,layout_height属性设置为match_parent

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><HorizontalScrollViewandroid:layout_width="wrap_content"android:layout_height="200dp"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal"><Viewandroid:layout_width="300dp"android:layout_height="match_parent"android:background="#00ff00"></View><Viewandroid:layout_width="300dp"android:layout_height="match_parent"android:background="#00aaff"></View></LinearLayout></HorizontalScrollView><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="400dp"android:background="#ff0000"></View><Viewandroid:layout_width="match_parent"android:layout_height="400dp"android:background="#aa00ff"></View></LinearLayout></ScrollView></LinearLayout>

四、按钮

Button由TextView派生,区别在于:
Button拥有默认按钮背景(紫色),而TextView无背景。
Button的内部文本默认居中对齐。
Button会默认将英文字母转为大写,testAllCaps可以设置是否转换。

ImageButton显示图片的图像按钮,继承自ImageView
ImageButton只能显示图片,不能显示文本
ImageButton的图像可按比例缩放,Button背景设置的图像会拉伸变形
Button只能靠背景显示一张图片,ImageButton可在前景和背景显示图片,从而实现两张图片叠加效果

例子:设置三个按钮,分别启动和禁用第三个按钮,禁用按钮需要长按才能禁用,第三个按钮点击则显示时间。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/button_begin_click"android:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:text="启用按钮"android:textSize="17sp"/><Buttonandroid:id="@+id/button_disable_click"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="禁用按钮"android:textSize="17sp" /></LinearLayout><Buttonandroid:id="@+id/button_test_click"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="测试禁用的按钮"android:textSize="17sp"android:enabled="false"/><TextViewandroid:id="@+id/button_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="查看测试禁用按钮的结果"android:textSize="17sp"android:textColor="#000000"/></LinearLayout>
package com.example.myapplication.utils;import java.text.SimpleDateFormat;
import java.util.Date;public class DateTime {public static String getNowTime(){SimpleDateFormat simpleDateFormat=new SimpleDateFormat("HH:mm:ss");return  simpleDateFormat.format(new Date());}
}
package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import com.example.myapplication.utils.DateTime;public class ButtonTextActivity extends AppCompatActivity {private Button button_test_click;private TextView button_view;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_button_text);Button button_begin_click=findViewById(R.id.button_begin_click);Button button_disable_click= findViewById(R.id.button_disable_click);button_test_click = findViewById(R.id.button_test_click);button_view = findViewById(R.id.button_text_view);button_begin_click.setOnClickListener(new MyOnclickListener());button_test_click.setOnClickListener(new MyOnclickListener());button_disable_click.setOnLongClickListener(new MyOnclickLongListener());}class MyOnclickListener implements View.OnClickListener{@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.button_begin_click:button_test_click.setEnabled(true);break;case R.id.button_test_click:String time=String.format("当前时间:%s", DateTime.getNowTime());button_view.setText(time);}}}class MyOnclickLongListener implements View.OnLongClickListener{@Overridepublic boolean onLongClick(View view) {button_test_click.setEnabled(false);return true;}}}

file

五、控件综合训练(简易计算器)

  1. Strings.xml
<resources><string name="app_name">My Application</string><string name="text2">Activity Main</string><string name="simple_calculator">简易计算器</string><string name="cancel">CE</string><string name="divide">÷</string><string name="clear">C</string><string name="multiply">+</string><string name="ride">*</string><string name="minus">-</string><string name="nine">9</string><string name="eight">8</string><string name="seven">7</string><string name="six">6</string><string name="five">5</string><string name="four">4</string><string name="three">3</string><string name="two">2</string><string name="one">1</string><string name="zero">0</string><string name="reciprocal">1/X</string><string name="doc">.</string><string name="equal">=</string><string name="root"></string>
</resources>
  1. dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><dimen name="button_font_size">30sp</dimen><dimen name="button_height">90dp</dimen></resources>
  1. layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#EEEEEE"android:orientation="vertical"android:padding="5dp"><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/simple_calculator"android:textColor="@color/black"android:gravity="center"android:textSize="30sp"/><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"android:text="0"android:textColor="@color/black"android:lines="8"android:textSize="25sp"android:gravity="right|bottom"/><GridLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:columnCount="4"android:rowCount="5"><Buttonandroid:id="@+id/btn_cancel"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/cancel"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_divide"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/divide"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_ride"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/ride"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_clear"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/clear"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_seven"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/seven"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_eight"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/eight"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_nine"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/nine"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_multi"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/multiply"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_four"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/four"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_five"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/five"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_six"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/six"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_minus"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/minus"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_one"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/one"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_two"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/two"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_three"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/three"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_root"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/root"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_reciprocal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/reciprocal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_zero"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/zero"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_doc"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/doc"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_equal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:text="@string/equal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/></GridLayout></LinearLayout></ScrollView>
</LinearLayout>
  1. 主类
package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class CalculatorActivity extends AppCompatActivity implements View.OnClickListener {private TextView tv_result;//第一个操作数private String firstNum="";//操作符号private String operator="";//第二个操作数private String secodeNum="";//计算结果private String result="";//显示的文本private String showText="";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_calculator);tv_result = findViewById(R.id.tv_result);findViewById(R.id.btn_cancel).setOnClickListener(this);findViewById(R.id.btn_divide).setOnClickListener(this);findViewById(R.id.btn_ride).setOnClickListener(this);findViewById(R.id.btn_clear).setOnClickListener(this);findViewById(R.id.btn_seven).setOnClickListener(this);findViewById(R.id.btn_eight).setOnClickListener(this);findViewById(R.id.btn_nine).setOnClickListener(this);findViewById(R.id.btn_multi).setOnClickListener(this);findViewById(R.id.btn_four).setOnClickListener(this);findViewById(R.id.btn_five).setOnClickListener(this);findViewById(R.id.btn_six).setOnClickListener(this);findViewById(R.id.btn_minus).setOnClickListener(this);findViewById(R.id.btn_one).setOnClickListener(this);findViewById(R.id.btn_two).setOnClickListener(this);findViewById(R.id.btn_three).setOnClickListener(this);findViewById(R.id.btn_root).setOnClickListener(this);findViewById(R.id.btn_reciprocal).setOnClickListener(this);findViewById(R.id.btn_zero).setOnClickListener(this);findViewById(R.id.btn_doc).setOnClickListener(this);findViewById(R.id.btn_equal).setOnClickListener(this);}@Overridepublic void onClick(View view) {String inputText;inputText=((TextView) view).getText().toString();switch (view.getId()){case R.id.btn_cancel:if(operator.equals("")) {showText = showText.substring(0, showText.length() - 1);refreshOperate(showText);refreshText(showText);break;}if(secodeNum.equals("")&&!operator.equals("")){showText = showText.substring(0, showText.length() - 1);CE();refreshText(showText);break;}else{showText = showText.substring(0, showText.length() - 1);refreshOperate(showText);refreshText(result);break;}case R.id.btn_clear:clear();break;case R.id.btn_multi:case R.id.btn_divide:case R.id.btn_ride:case R.id.btn_minus:operator=inputText;refreshText(showText+operator);break;case R.id.btn_equal:double calculate_result=calculateFour();refreshOperate(String.valueOf(calculate_result));refreshText(showText+"="+result);break;//开根号case R.id.btn_root:double sqrt_result=Math.sqrt(Double.parseDouble(firstNum));refreshOperate(String.valueOf(sqrt_result));refreshText(showText+"√="+result);break;//求导数case R.id.btn_reciprocal:double reciprocal_result=1.0/Double.parseDouble(firstNum);refreshOperate(String.valueOf(reciprocal_result));refreshText(showText+"/="+result);break;default:if (result.length()>0&&operator.equals("")){clear();}if(operator.equals("")){firstNum=firstNum+inputText;}else{secodeNum=secodeNum+inputText;}if(showText.equals("0")&&!inputText.equals(".")){refreshText(inputText);}else {refreshText(showText + inputText);}break;}}private  void cancel(){}private void clear(){refreshOperate("");refreshText("");}private double calculateFour(){switch (operator){case "+":return Double.parseDouble(firstNum)+Double.parseDouble(secodeNum);case "-":return Double.parseDouble(firstNum)-Double.parseDouble(secodeNum);case "*":return Double.parseDouble(firstNum)*Double.parseDouble(secodeNum);default:return Double.parseDouble(firstNum)/Double.parseDouble(secodeNum);}}private void CE(){ //7+operator="";}private void refreshOperate(String new_result){result=new_result;firstNum=result;secodeNum="";operator="";}private void refreshText(String text){showText=text;tv_result.setText(showText);}
}

并非是什么完美计算器,仅是复习以上知识操作使用。

file

六、Activity

从当前页面跳转到新页面:
startActivity(new intent(源页面.this,目标页面.class))
当前页面返回上一个页面:
finish();

activity的生命周期:
onCreate 创建活动,把页面加载进内存,进入初始状态
onStart 开始活动,把活动页面显示到屏幕,就绪态
onResume 恢复活动,活动页面进入活跃状态
onPause 暂停活动,页面不能正常交互
onStop 停止活动,页面不在屏幕
onDestroy 销毁活动,回收系统资源,从内存清除
onRestart 重启活动,重新加载内存的页面数据
onNewIntent 重用已有的实例

file

Activity启动模式(栈)
默认启动模式standard,启动的Activity依照顺序被依次压入Task栈。
栈顶复用模式singleTop,栈顶Activity为我们新建的Activity,不会重新创建新的Activity。
栈内复用模式singleTask,栈内存在目标Activity实例,则将task内对应Activity实例之上的Activity出栈,并
将对应Activity置于栈顶。
全局唯一模式singleInstance,为目标Activity创建新的Task栈,新的Task栈只有这一个Activity,如
已经创建目标Activity,则不创建新的Task,将以前的Activity唤醒。
启动模式的设置:intent.setFlags()代码中启动,Mainfest.xml中动态设置launch。

file

例子:登录页面进行登录成功后,即使后退,也不能返回登录页面,而是直接退出程序。

package com.example.activity;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class LoginInputActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login_input);Button btn_login=findViewById(R.id.btn_login);btn_login.setOnClickListener(new MyOnclickListen());}class MyOnclickListen implements View.OnClickListener{@Overridepublic void onClick(View view) {Intent intent=new Intent(LoginInputActivity.this,LoginSuccessActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}}
}

通过设置启动模式来完成,一旦登录则会清空当前活动栈中的所有实例,然后再同时启动开辟新任务的活动栈,这样登录后,再点击返回则会直接退出程序。

  1. Intent

Intent各个组件之间信息沟通桥梁,用于组件之间通信,主要完成工作是本次通信请求从哪来,到哪去,要怎么走
发起方携带本次通信需要的数据,接收方从收到的意图中解析数据。
发起方若判断接收方处理结果,意图就要负责让接收方回应答数据。

显示Intent,直接指定来源活动与目标活动,精确匹配,三种方式
直接Intent函数中指定:new Intent()
调用意图对象:setClass()
调用意图对象setComponent()

隐式Intent,没有明确指定要跳转的目标活动,只给出一个动作字符串匹配,属于模糊匹配
通过setAction,url,setData()指定动作和数据
常见的隐式动作有:

file

例子1:使用隐式Intent直接进行拨号,发送短信,或跳转到其它APP

package com.example.activity;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class IntentActivity extends AppCompatActivity implements View.OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_intent);Button btn_dail=findViewById(R.id.btn_dail);Button btn_cms=findViewById(R.id.btn_cms);Button btn_my=findViewById(R.id.btn_mypage);btn_dail.setOnClickListener(this);btn_cms.setOnClickListener(this);btn_my.setOnClickListener(this);}@Overridepublic void onClick(View view) {String phone="123456";Intent intent=new Intent();switch (view.getId()){case R.id.btn_dail:intent.setAction(Intent.ACTION_DIAL);Uri uri=Uri.parse("tel:"+phone);intent.setData(uri);startActivity(intent);break;case R.id.btn_cms:intent.setAction(Intent.ACTION_SENDTO);Uri uri2=Uri.parse("smsto:"+phone);intent.setData(uri2);startActivity(intent);break;case R.id.btn_mypage:intent.setAction("android.intent.action.Aiwin");intent.addCategory(Intent.CATEGORY_DEFAULT);startActivity(intent);break;}}
}<intent-filter><action android:name="android.intent.action.Aiwin" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>

最后跳转自己的APP,需要在mainfestxml中添加intent-filter

例子2:A页面发送信息给B页面,B页面再返回回应信息给A页面,需要通过registerForActivityResult()

package com.example.activity;import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class ActRequestActivity extends AppCompatActivity implements View.OnClickListener{private ActivityResultLauncher<Intent> register;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_request);Button btn_send=findViewById(R.id.btn_request);TextView btn_receive=findViewById(R.id.btn_receive);btn_send.setOnClickListener(this);register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult result) {if(result!=null){Intent intent=result.getData();if(intent!=null&result.getResultCode()== Activity.RESULT_OK){Bundle bundle=intent.getExtras();String message=bundle.getString("response");btn_receive.setText(message);}}}});}@Overridepublic void onClick(View view) {Intent intent=new Intent(this,ActResponseActivity.class);Bundle bundle=new Bundle();bundle.putString("message","你睡了吗?");intent.putExtras(bundle);register.launch(intent);}
}
package com.example.activity;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class ActResponseActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_response);TextView request=findViewById(R.id.btn_request);Button btn_response=findViewById(R.id.btn_response);Bundle bundle=getIntent().getExtras();String request_content=bundle.getString("message");request.setText(request_content);btn_response.setOnClickListener(this);}@Overridepublic void onClick(View view) {Intent intent=new Intent();Bundle bundle=new Bundle();bundle.putString("response","我没睡,我爸妈不在家");intent.putExtras(bundle);setResult(ActRequestActivity.RESULT_OK,intent);finish();}
}
  1. 应用页面注册快捷方式

在安卓7以后,可以长按页面图标,弹出一些快捷方式,比如长按微信会弹出扫一扫,付款码等
点击即可直接跳转到该页面。

例子:在xml目录创建shortcuts.xml,先修改Mainfest.xml文件

<activityandroid:name=".ActStartActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><meta-dataandroid:name="android.app.shortcuts"android:resource="@xml/shortcuts" /></activity>

配置shortcuts.xml文件


<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"><shortcutandroid:enabled="true"android:icon="@mipmap/ic_launcher"android:shortcutId="first"android:shortcutLongLabel="@string/shortcutLongLabel_first"android:shortcutShortLabel="@string/shortcutShortLabel_first"><!-- targetClass指定了点击该项菜单后要打开哪个活动页面 --><intentandroid:action="android.intent.action.VIEW"android:targetClass="com.example.activity.ActStartActivity"android:targetPackage="com.example.activity" /><categoriesandroid:name="android.shortcut.conversation" /></shortcut><shortcutandroid:enabled="true"android:icon="@mipmap/ic_launcher"android:shortcutId="second"android:shortcutLongLabel="@string/shortcutLongLabel_second"android:shortcutShortLabel="@string/shortcutShortLabel_second"><!-- targetClass指定了点击该项菜单后要打开哪个活动页面 --><intentandroid:action="android.intent.action.VIEW"android:targetClass="com.example.activity.ActStartActivity"android:targetPackage="com.example.activity" /><categoriesandroid:name="android.shortcut.conversation" /></shortcut></shortcuts>

效果:
file

七. 中级控件

  1. Shape图

形状图形 Shape,形状图形的定义文件是以shape标签为根节点的XML描述文件,一般有四种类型的形状:
rectangle 矩形,默认值
oval 椭圆,corners节点失效
line 直线,必须设置stroke节点
ring 圆环
其中XML中能设置的有:size尺寸,stroker描边,corners圆角,solid填充,padding间隔,gradient渐变

如设置一个椭圆形:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="#ff66aa"/><stroke android:width="1dp" android:color="#aaaaaa"/></shape>
  1. 九宫格图片

在Android Stdio中,可以直接把PNG图片转成九宫格图片,利用九宫格图片,能够使图片被拉伸但是不变形,
能够用于适应不同的手机屏幕。

  1. 状态列表图形

简单来说,就是按钮被按下和没被按下显示不同的颜色或者形状等,以便于用户区分按了哪一个按钮,可通过StateListDrawable完成。状态的取值常用的有pressed、checked、focused、selected

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true" android:drawable="@android:drawable/button_onoff_indicator_on"/><item android:drawable="@android:drawable/button_onoff_indicator_off"/></selector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="默认样式按钮"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:background="@drawable/drawable_nine_selector"android:padding="5dp"android:text="定制样式按钮"/></LinearLayout>

在这里插入图片描述

  1. checkbox
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="5dp"><CheckBoxandroid:id="@+id/ck_system"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="5dp"android:text="系统的CheckBox" /><CheckBoxandroid:id="@+id/ck_custom"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:button="@drawable/checkbox_selector"android:padding="5dp"android:text="CheckBox换图标"/></LinearLayout>
package com.example.middlecontrolactivity;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;public class CheckBoxAcivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_check_box_acivity);CheckBox ck_system=findViewById(R.id.ck_system);CheckBox ck_custom=findViewById(R.id.ck_custom);ck_system.setOnCheckedChangeListener(this);ck_custom.setOnCheckedChangeListener(this);}@Overridepublic void onCheckedChanged(CompoundButton compoundButton, boolean b) {String desc=String.format("您%s了这个CheckBox",b ? "勾选":"没勾选");compoundButton.setText(desc);}
}
  1. Switch

与checkbox使用是一致的,都是从Compuound类继承而来

textOn:设置右侧开启时文本
textOff:设置左侧关闭时文本
track:设置开关轨道的背景
thumb:设置开关标识图标
  1. RadioButton

一般单选按钮只允许选择一个,需要放在RadioGroup里面,对RadioGroup进行监听

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="请选择你的性别"android:textColor="@color/black"android:textSize="17sp"/><RadioGroupandroid:id="@+id/rg_rb"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rb_male"android:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:text=""/><RadioButtonandroid:id="@+id/rb_female"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text=""/></RadioGroup><TextViewandroid:id="@+id/tv_result"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="17sp"android:textColor="@color/black"/></LinearLayout>
package com.example.middlecontrolactivity;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.TextView;public class RadioButtonActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {private TextView tv_result;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_radio_button);RadioGroup rg_rb=findViewById(R.id.rg_rb);tv_result=findViewById(R.id.tv_result);rg_rb.setOnCheckedChangeListener(this);}@Overridepublic void onCheckedChanged(RadioGroup radioGroup, int i) {switch (i){case R.id.rb_male:tv_result.setText("你选择的是男性");break;case R.id.rb_female:tv_result.setText("你选择的女性");break;}}
}
  1. EditText

hint:指定提示文本的内容
maxLength:指定文件允许输入的最大长度
inputType:指定输入的文本类型

输入类型说明
text文本
testPassword文本密码
number整型数
numberSigned带符号的数字
numberDecimal带小数点的数字
numberPassword数字密码
datetime时间日期格式,数字,横线,斜杆,空格,冒号
date日期格式,数字,横线,斜杠
time时间格式

例子:简单的登录判断程序

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="5dp"android:orientation="vertical"><EditTextandroid:id="@+id/phone"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入手机号"android:inputType="phone"android:textColorHint="@color/black"
/><EditTextandroid:id="@+id/password"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入密码"android:inputType="textPassword"android:textColorHint="@color/black"/><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="提交"android:textSize="17sp"android:layout_gravity="right" /><TextViewandroid:id="@+id/text"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="17sp"/></LinearLayout>
package com.example.middlecontrolactivity;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;public class EditTextActivity extends AppCompatActivity implements View.OnClickListener {private  Button button;private  EditText phone;private  EditText password;private TextView v;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_edit_text);v=findViewById(R.id.text);button =findViewById(R.id.button);phone=findViewById(R.id.phone);password=findViewById(R.id.password);button.setOnClickListener(this);}@Overridepublic void onClick(View view) {String p=phone.getText().toString();String pass=password.getText().toString();if(p.equals("123456") && pass.equals("123456")){v.setText("登录成功");}else{v.setText("登录失败");}}
}

相关文章:

安卓开发学习记录(持续学习)

文章目录前言工具创建项目简单控件即UI一、界面显示与逻辑处理二、文本三、布局四、按钮五、控件综合训练(简易计算器)六、Activity七. 中级控件前言 最近在有在持续学习Java的安卓开发&#xff0c;不断的把知识记录下。 工具 Android Studio安装 [Studio安装][1] [1]: https…...

【redis】AOF日志:宕机了,Redis如何避免数据丢失

专题3-AOF日志&#xff1a;宕机了&#xff0c;Redis如何避免数据丢失 因为redis的数据是存在内存中的&#xff0c;一旦服务器宕机&#xff0c;内存中的数据会全部丢失。 AOF&#xff1a;redis先执行命令&#xff0c;把数据写入内存&#xff0c;然后才记录日志。 AOF优点&…...

第三章Vue中的Ajax

文章目录Vue脚手架配置代理为什么要配置代理服务器什么是跨域&#xff1f;代理跨域CORS跨域利用Vue-CLI配置代理服务器GitHub用户搜索案例本案例需要下载axios库&#xff1a; npm install axiosVue脚手架配置代理 为什么要配置代理服务器 什么是跨域&#xff1f; 跨域资源共…...

在 Python3 中使用 JSON

在 Python3版本中使用 JSON 本教程将会教我们如何使用 Python 编程语言编码和解码 JSON。 环境 在python3中&#xff08;以及python2.6版本后的python2版本&#xff09;内置了JSON模块&#xff0c;无需额外安装另外的JSON模块。 简介 JSON模块是python内置的用来进行pytho…...

图神经网络GNN介绍

目录标题图神经网络基础图基本模块定义图的邻接矩阵点特征的更新&#xff08;重构&#xff09;多层GNN图卷积GCN模型GCN基本思想网络层数&#xff1a;基本计算图注意力机制graph attention networkT-GCN序列图神经网络图相似度图神经网络基础 图基本模块定义 三个特征&#x…...

【面试】TCP、UDP、Socket、HTTP网络编程面试题

文章目录什么是网络编程网络编程中两个主要的问题网络协议是什么为什么要对网络协议分层计算机网络体系结构1 TCP / UDP1.1 什么是TCP/IP和UDP1.2 TCP与UDP区别&#xff1a;1.3 TCP和UDP的应用场景&#xff1a;1.4 形容一下TCP和UDP1.5 运行在TCP 或UDP的应用层协议分析。什么是…...

Python语言的文件读写

&#x1f951;高级语言有很多共同之处&#xff0c;在文件读写这一部分我们就可以类比着之前我们过的C语言的文件读写的操作进行处理。 &#x1f951;还记得我们C语言当中的文件进行操作时所需要的哪些步骤吗?文件打开&#xff0c;文件读/写操作&#xff0c;文件关闭。我们的Py…...

面向对象 ( 上 )

Java面向对象 ( 上 ) 观看b站尚硅谷视频做的笔记 1、 面向过程 (POP) 与面向对象 (OOP) 2、类和对象 2.1、Java 类及类的成员 属性&#xff1a;对应类中的成员变量 行为&#xff1a;对应类中的成员方法。 2.2、类与对象的创建及使用 一、设计类&#xff0c;就是设计类的…...

Node.js学习笔记——会话控制

一、介绍 所谓会话控制就是对会话进行控制 HTTP 是一种无状态的协议&#xff0c;它没有办法区分多次的请求是否来自于同一个客户端&#xff0c; 无法区分用户 而产品中又大量存在的这样的需求&#xff0c;所以我们需要通过 会话控制 来解决该问题 常见的会话控制技术有三种&a…...

tsconfig.json参数详解

tsconfig.json是ts编译器的配置文件&#xff0c;ts编译器可以根据他的信息来对代码进行编译。 想要学习这篇文章小伙伴&#xff0c;可以先去看看下面文章&#xff0c;可以明白tsconfig.json的由来以及如何编译&#xff1a; 在vscode中使用Typescript并运行_typescript vscode…...

Pyecharts Geo绘制可视化地图并展示坐标位置

文章目录 Pyecharts Geo绘制可视化地图安装需要的模块绘制出地图生成空白地图修改参数,调整地图输出格式地图上展示坐标位置输入坐标点将坐标点添加入系列并配置系列完整代码参考文献Pyecharts Geo绘制可视化地图 安装需要的模块 pip install pyecharts绘制出地图 生成空白…...

什么是Hbuilder?--前端工具IDE

一&#xff0c;简介HBuilder 1.1HBuilder HBuilder是DCloud&#xff08;数字天堂&#xff09;推出的一款支持HTML5的Web开发IDE。HBuilder的编写用到了Java、C、Web和Ruby。HBuilder本身主体是由Java编写。它基于Eclipse&#xff0c;所以顺其自然地兼容了Eclipse的插件从Fron…...

07-centos-更改数据源、打补丁、查看内核

本文主要是介绍linux-centos的常用操作 更改数据源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo 查看内核 [rootcentos02 ~]# uname -a Linux centos02 2.6.32-642.el6.x86_64 #1 SMP Tue May 10 17:27:01 UTC 2016 x86_64 …...

flac格式如何转mp3,3种简单方法值得收藏

flac格式如何转mp3&#xff1f;mp3是小伙伴们所熟知的音频格式&#xff0c;相信flac格式也一定有小伙伴知道&#xff0c;它是一种无损音频压缩格式&#xff0c;是目前流行的数字音乐文件格式之一。那么为什么要将flac格式转换成mp3格式呢&#xff0c;这里小编就给大家讲一讲fla…...

停车位 蓝桥杯模拟

【问题描述】 小蓝要在路边划分停车位。 他将路边可停车的区域划分为L个整数小块&#xff0c;编号1至L。一个车位需要连续的K 个小块&#xff0c;停车位不能重 叠。有的小块属于井盖、消防通道等区域&#xff0c;不能停车。 请问小蓝最多划分出多少个停车位&#xff1f; 【输入…...

ftrace使用实战

诉求&#xff1a;遇到一个问题 echo blocked > /sys/class/block/sdb/device/state 报非法参数&#xff0c;想要知道根因&#xff0c;但是对这块内核代码不熟悉&#xff0c;不知道从哪里下手&#xff0c;那就先用ftrace看看内核调用栈&#xff0c;如下所示。 rootrlk:/home…...

【C#进阶】C# 不安全代码

序号系列文章20【C#进阶】C# 泛型21【C#进阶】C# 匿名方法22【C#进阶】C# 多线程文章目录前言1、什么是不安全代码&#xff1f;2、如何编译不安全代码&#xff1f;3、指针类型4、指针执行的运算符和语句5、固定大小的缓冲区6、函数指针7、不安全代码的总结结语前言 &#x1f4d…...

Docker安装部署ElasticSearch

1.部署单点ElasticSearch 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让ElasticSearch和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net1.2.拉取镜像 考虑到ElasticSearch的兼容性&#xff0c;这里ElasticSearch、kiba…...

【新2023Q2模拟题JAVA】华为OD机试 - 快递业务站

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:快递业务站 题目 快递业务范…...

OpenCV入门(二十四)快速学会OpenCV 23 傅里叶变换

OpenCV入门&#xff08;二十四&#xff09;快速学会OpenCV 23 傅里叶变换1.傅里叶变换理论概述2.Numpy实现傅里叶变换2.1 傅里叶变换2.2 傅里叶逆变换2.3 高通滤波3.OpenCV实现傅里叶变换3.1 实现傅里叶变换3.2 实现傅里叶逆变换3.3 低通滤波作者&#xff1a;Xiou 1.傅里叶变换…...

线段树合并

前置知识&#xff1a;权值线段树&#xff0c;动态开点。 引入 我们先来看一道题&#xff1a; 永无乡包含 nnn 座岛&#xff0c;给出每座岛的重要度的排名&#xff0c;名次用 111 到 nnn 来表示。一开始有 mmm 条边连接&#xff0c;接下来有 qqq 次操作。操作分两种&#xff…...

研发效能 | DevOps如何改变游戏公司工作方式?

如果你是游戏开发者&#xff0c;那么在过去几年里&#xff0c;你可能会觉得有人给了你一把双刃剑。 整个行业不断蓬勃发展&#xff0c;但玩家的预期值也越来越高。玩家们总是希望游戏体验能够更快、更真实、更具创造性。此外&#xff0c;他们还希望能够定期推出新的游戏和更新…...

Mongo聚合和Springboot整合Mongo聚合

聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。 语法格式:db.集合名称.aggregate({管道:{表达式}}) 常用管道如下: $group: 将集合中的⽂…...

第06章_索引的数据结构

第06章_索引的数据结构 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目…...

不确定的市场,确定的增长,海尔智家2022全球再逆增

文|螳螂观察 作者| 余一 上市公司2022年年报逐渐进入密集披露期&#xff0c;在当前的年报季窗口&#xff0c;各家公司的业绩情况被高度关注。 3月30日晚&#xff0c;海尔智家发布了2022年财报。财报显示&#xff0c;2022年海尔智家实现收入2435.14亿元&#xff0c;同比增长7…...

测试老鸟手把手教你python接口自动化测试项目实战演示

目录 前言 一、项目准备 二、项目流程 三、完整代码 四、总结 前言 在进行接口自动化测试项目实战之前&#xff0c;我们需要先了解什么是接口自动化测试。接口自动化测试是通过自动化脚本模拟用户请求和服务器响应的过程&#xff0c;以检测接口是否符合预期&#xff0c;确…...

一起来学5G终端射频标准(Coherent UL-MIMO测试要求)

01 — Coherent UL-MIMO测试要求 首先什么是Coherent&#xff1f;它的英文释义是&#xff1a;&#xff08;of ideas, thoughts, argument, theory, or policy) logical and consistent&#xff0c;翻译过来就是&#xff1a;&#xff08;看法、思想、论证、理论或政策等&…...

计算广告(五)

Nobid Nobid&#xff08;在某手有时也叫MCB&#xff0c;在Facebook叫Lowest Cost&#xff09;是指广告主不用&#xff08;也不能&#xff09;对转化成本进行出价&#xff0c;而是出一个预算&#xff08;大多数是日预算&#xff09;&#xff0c;然后投放平台的目标是在时间范围…...

排序输入的高效霍夫曼编码 | 贪心算法 3

前面我们讲到了 贪心算法的哈夫曼编码规则&#xff0c;原理图如下&#xff1a; 如果我们知道给定的数组已排序&#xff08;按频率的非递减顺序&#xff09;&#xff0c;我们可以在 O(n) 时间内生成霍夫曼代码。以下是用于排序输入的 O(n) 算法。1.创建两个空队列。2.为每个唯一…...

奇异值分解(SVD)和图像压缩

在本文中&#xff0c;我将尝试解释 SVD 背后的数学及其几何意义&#xff0c;还有它在数据科学中的最常见的用法&#xff0c;图像压缩。 奇异值分解是一种常见的线性代数技术&#xff0c;可以将任意形状的矩阵分解成三个部分的乘积&#xff1a;U、S、V。原矩阵A可以表示为&#…...