1. 学习 K8S: Docker 基础

news2024/9/23 3:24:00

学习 K8S: Docker 基础

1. Docker 的诞生

1.1 首次展示

2013 年 3 月 15 日,在北美的圣克拉拉市召开了一场 Python 开发者社区的主题会议 PyCon,研究和探讨各种 Python 开发技术和应用,
在当天的会议日程快结束时,有一位名为 Solomon Hykes 开发者(Docker 公司的创始人)在“闪电演讲”(lighting talk)的小环节,用了 5 分钟的时间,做了题为 “The future of Linux Containers” 的演讲,展示了 Docker 技术,不过临近末尾因为超时而被主持人赶下了台。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jGizkwQX-1693031721771)(img/Docker演讲.png)]

1.2 Docker 的选择

使用 Docker 有两个选择:

  • Docker Desktop: 专门针对个人使用而设计的,支持 Mac 和 Windows 快速安装,具有图形化界面。(不推荐,属于商业产品,夹带私货)
  • Docker Engine: Docker 最初的形态,被广泛使用在服务器上,只能使用命令行操作。(完全免费)

1.3 安装 Docker Engine

Ubuntu 安装命令:

sudo apt install -y docker.io

启动 Docker 服务并将当前用户加入 Docker 组:

sudo service docker start         #启动docker服务
sudo usermod -aG docker ${USER}   #操作 Docker 必须要有 root 权限,直接使用 root 用户不够安全

验证 Docker 是否安装成功,成功会输出 Docker 客户端和服务器各自的版本信息:

docker version

显示当前 Docker 系统相关的信息,例如 CPU、内存、容器数量、镜像数量、容器运行时、存储文件系统等等:

docker info

1.4 Docker 的命令

所有的 Docker 操作都是如下形式:以 docker 开始,跟上一个具体的子命令。

列出当前系统里运行的容器:

docker ps

查看所有的容器:

docker ps -a

获取帮助文档信息,查看命令清单和更详细的说明:

docker help

从外部的镜像仓库(Registry)拉取一个镜像:

docker pull

列出当前 Docker 所存储的所有镜像:

docker images

从镜像中启动容器:

docker run

1.5 Docker 命令初步实践

拉取 busybox 镜像:

docker pull busybox

从 busybox 镜像中启动容器,并执行 echo 命令:

docker run busybox echo hello world

1.6 Docker 的架构

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YMSvQUDT-1693031721772)(img/Docker架构.png)](https://img-blog.csdnimg.cn/c5559ca45f244452b1fea4116d07110e.png)

客户端 Docker client 接收命令行的输入,并与 Docker Engine 里的后台服务 Docker daemon 通信。
镜像存储在远端的仓库 Registry 里,客户端可以通过 build、pull、run 等命令向 Docker daemon 发送请求。
Docker daemon 是容器和镜像的管理者,负责从远端拉取镜像、在本地存储镜像,还有从镜像生成容器、管理容器等所有功能,是实际命令的执行者。

展示 Docker client 到 Docker daemon 再到 Registry 的详细工作流程:

docker run hello-world

该命令的输出解析:

  • 先检查本地镜像:
  • 如果没有就从远程仓库拉取:
  • 再运行容器:
  • 最后输出运行信息:

小结

Docker 的起源
Docker 的产品
Docker 的架构和执行流程
Docker 的相关命令

2. 容器的本质

广义上,容器技术是动态的容器、静态的镜像和远端的仓库三者的组合。

2.1 容器与集装箱

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q9S7dQwt-1693031721772)(img/Docker与集装箱.png)]

集装箱:集装箱的作用是标准化封装各种货物,一旦打包完成之后,就可以从一个地方迁移到任意的其他地方。
容器:容器封装的运行中的应用程序(进程),把进程与外界隔离开,让进程与外部系统互不影响。即,容器是被隔离的进程。

2.2 隔离

安全

虽然 Linux 提供了用户权限控制,能够限制进程只访问某些资源,但这个机制还是比较薄弱的,和真正的“隔离”需求相差得很远。

使用容器技术,可以让应用程序运行在一个有严密防护的“沙盒”(Sandbox)环境之内,它只可以在这个环境里自由活动,从而保证了容器外系统的安全。

资源隔离

容器技术的另一个本领就是为应用程序加上资源隔离,在系统里切分出一部分资源,让它只能使用指定的配额,比如只能使用一个 CPU,只能使用 1GB 内存等等,可以避免容器内进程的过度系统消耗,充分利用计算机硬件,让有限的资源能够提供稳定可靠的服务。

2.3 容器与虚拟机

都是虚拟化技术。
目的都是隔离资源,保证系统安全,尽量提高资源的利用率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uPw0UWUI-1693031721773)(img/容器和虚拟机.png)]

实际上,Docker 只是辅助建立隔离环境,容器并不直接运行在 Docker 上,而是基于 Linux 操作系统运行。

实现的角度:

  • 虚拟机虚拟化出来的是硬件,需要在上面再安装一个操作系统后才能够运行应用程序,而硬件虚拟化和操作系统都比较“重”,会消耗大量的 CPU、内存、硬盘等系统资源
  • 容器(即图中的 Docker),它直接利用了下层的计算机硬件和操作系统,因为比虚拟机少了一层,所以自然就会节约 CPU 和内存,显得非常轻量级,能够更高效地利用硬件资源。不过,因为多个容器共用操作系统内核,应用程序的隔离程度就没有虚拟机那么高了。

容器和虚拟机可以结合使用,也可以独立使用。

隔离的实现:

  • 虚拟机使用的是 Hypervisor(KVM、Xen 等)
  • 容器使用 Linux 操作系统内核技术:
    • namespace:可以创建出独立的文件系统、主机名、进程号、网络等资源空间,
    • cgroup: Linux Control Group,用来实现对进程的 CPU、内存等资源的优先级和配额限制
    • chroot: 可以更改进程的根目录,也就是限制访问文件系统

小结

容器实现了与外部系统的隔离。
容器限制了进程能访问的资源,并且相比于虚拟机更加轻量级和高效。
容器的基本实现:namespace、cgroup、chroot

3. 容器化的作用

3.1 容器化的应用

容器是由操作系统动态创建的,因此需要把初始运行环境固定下来,保存成一个静态的文件,以便存放、传输、版本化管理了。

镜像:镜像打包了应用程序,不仅有基本的可执行文件,还有应用运行时的整个系统环境。
容器化应用:应用程序不直接和操作系统打交道,而是封装成镜像,再交给容器环境去运行。

镜像和容器的关系:

镜像就是静态的应用容器,容器就是动态的应用镜像,可以相互转换。

获取一个打包了 busybox 的镜像:

docker pull busybox

3.2 常见的镜像操作

定位镜像,名字+标签:

  • 名字:表示应用的身份,如 busybox、Alpine、Nginx、Redis
  • 标签:区分不同版本的应用而做的额外标记,如版本号、项目代号、版本号加操作系统名。默认标签名是 lastest

采用名字+标签的方式,拉取镜像:

docker pull alpine:3.15
docker pull ubuntu:jammy
docker pull nginx:1.21-alpine
docker pull nginx:alpine
docker pull redis

image id :

  • 镜像唯一的标识,不同的名字+标签可能定位到相同的镜像
  • 十六进制形式且唯一,可以采用“短路操作”,只要该 id 的前 x 位是在当前镜像列表中相对唯一。

删除镜像:

docker rmi redis  # 使用名字删除
docker rmi sx2 # 采用id删除

3.3 常见的容器操作

将静态的镜像运行成为容器:

docker run 设置参数 镜像id|镜像名 运行命令

-h srv 容器的运行参数,alpine 镜像名,hostname 表示在容器里运行的“hostname”程序。

docker run -h srv alpine hostname

-it:表示开启一个交互式操作的 Shell,可以直接进入容器内部
-d:表示让容器在后台运行
–name: 可以为容器起一个名字,不用这个参数,Docker 会分配一个随机的名字。

eg:

docker run -d nginx:alpine            # 后台运行Nginx
docker run -d --name red_srv redis    # 后台运行Redis
docker run -it --name ubuntu 2e6 sh   # 使用IMAGE ID,登录Ubuntu18.04

查看容器运行的状态:

docker ps

CONTAINER ID: 唯一标识容器

强制停止容器:

docker stop  容器名字|CONTAINER ID

再次启动停止的程序:

docker start 容器名字|CONTAINER ID

删除容器(而非镜像):

docker rm 容器名字|CONTAINER ID

自动删除不需要的容器(只要运行完毕就自动清除:

docker run -d --rm 容器名字|CONTAINER ID #   --rm:不保存容器,只要运行完毕就自动清除

小结

镜像是容器的静态形式。
容器化的应用。
镜像和容器的操作。

4. Dockerfile

4.1 镜像的内部机制

资源冗余:为了保证容器运行环境的一致性,镜像必须把应用程序所在操作系统的根目录 rootfs 都包含进来,虽然容器共享了操作系统内核,但是重复的打包资源,会造成大量的冗余。
Layer:抽取重复的部分并共享,容器镜像内部由许多的镜像层组成,每层都是只读不可修改的一组文件,相同的层可以在镜像之间共享,多个层像搭积木一样堆叠,使用“Union FS 联合文件系统”技术把它们合并在一起,形成容器最终看到的文件系统。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5cjHngHO-1693031721774)(img/docker%20layer.png)]

查看镜像的分层信息:

docker inspect 容器名字|CONTAINER ID

4.2 Dockerfile

Dockerfile:

  • 记录了一系列的构建指令,比如选择基础镜像、拷贝文件、运行脚本等等。
  • 每个指令都会生成一个 Layer,因此最好精简命令。
  • 按顺序执行。

最简单的 Dockerfile 示例:

# Dockerfile.busybox
FROM busybox                  # 选择基础镜像
CMD echo "hello world"        # 启动容器时默认运行的命令

使用 Dockerfile 创建镜像:

docker build -f dockerfile的文件名 文件路径(构建上下文)

如果省略-f 参数:docker build 就会在当前目录下找名字是 Dockerfile 的文件。如果只有一个构建目标的话,文件直接叫“Dockerfile”是最省事的。

-t 参数:指定镜像的标签(tag),Docker 会在构建完成后自动给镜像添加名字。

4.3 编写 Dockerfile

FROM:构建镜像的第一条指令必须是 FROM,选择基础镜像。
COPY:将开发测试时会产生一些源码、配置等文件打包进镜像中,源文件是构建上下文路径中的。
RUN:执行任意的 Shell 命令,Dockerfile 里一条指令只能是一行,在每行的末尾使用续行符 \,命令之间也会用 && 来连接,保证在逻辑上是一行。如果命令过长,就把这些 Shell 命令集中到一个脚本文件里,用 COPY 命令拷贝进去再用 RUN 来执行。
参数化运行:ARG 创建的变量只在镜像构建过程中可见,容器运行时不可见,而 ENV 创建的变量不仅能够在构建镜像的过程中使用,在容器运行时也能够以环境变量的形式被应用程序使用。
EXPOSE:声明容器对外服务的端口号

4.4 .dockerignore

.dockerignore:

  • 语法与 .gitignore 类似,排除那些不需要的文件。

小结

容器镜像是由多个只读的 Layer 构成的,同一个 Layer 可以被不同的镜像共享,减少了存储和传输的成本。
Dockerfile 的编写步骤
Docker build 命令的使用

5. Docker Hub

5.1 镜像仓库 Registry

一个全面的镜像管理服务站点,所有镜像都在这里保管,如同档案馆。

5.2 Docker Hub

如果没有明确指明镜像仓库地址, docker pull 将向 Docker Hub(默认镜像仓库)发送拉取请求。

Docker Hub 面向公众免费开放。

Docker Hub 的镜像分类:

  • 官方镜像:Docker 公司官方提供的高质量镜像,经过了严格的漏洞扫描,支持 x86_64、arm64 等多种硬件架构,还具有清晰易读的文档。(构建镜像的首选)
  • 认证镜像:大公司发行的,经过 Docker 官方认证的镜像。
  • 非官方镜像:
    • 半官方:成为“Verified publisher”需要向 Docker 公司交钱,部分公司不想交钱,如 OpenResty。
    • 纯粹民间镜像:个人上传到 Docker Hub,质量和安全无法得到保证。

Docker Hub 上的镜像命名规则:

  • 标签:通常是应用的版本号加上操作系统,版本号的格式为主版本号 + 次版本号 + 补丁号,有的标签还会加上 slim(表示这个镜像的内容是经过精简的)、fat(包含较多辅助工具)

5.3 上传镜像

  1. 在 Docker Hub 上注册一个用户
  2. 在本机上使用 docker login 命令
  3. 使用 docker tag 命令,给镜像改成带用户名的完整名字,表示镜像是属于这个用户的
  4. 用 docker push 把这个镜像推上去

5.4 离线环境

在内网环境里仿造 Docker Hub。

save 命令:将镜像导出为压缩包
load 命令:从压缩包导入 Docker

docker save ngx-app:latest -o ngx.tar
docker load -i ngx.tar

-i 和-o 表示使用标准输入输出流

小结

镜像仓库与 Docker Hub
上传镜像到 Docker Hub
离线使用 Docker

6. 容器与外部互通

6.1 拷贝容器内的数据

docker cp,如果源路径是宿主机那么就是把文件拷贝进容器,如果源路径是容器那么就是把文件拷贝出容器。容器内的路径表示容器id:路径

docker cp 062:/tmp/a.txt ./b.txt

6.2 共享宿主机上的文件

docker run 命令,-v 指定宿主机路径: 容器内路径, 即可把宿主机路径挂载到容器内的路径,让容器共享宿主机的文件。

docker run -d --rm -v /tmp:/tmp redis

6.3 网络互通

Docker 的三种网络模式:

  • null:没有网络,但允许其他的网络插件来自定义网络连接
  • host:直接使用宿主机网络,相当于去掉了容器的网络隔离,所有的容器会共享宿主机的 IP 地址和网卡。docker run --net=host
  • bridge: 桥接模式,默认的网络模式,容器和宿主机再通过虚拟网卡接入这个网桥。docker run --net=bridge

6.4 分配服务端口号

端口号映射需要使用 bridge 模式,并且在 docker run 启动容器时使用 -p 参数指定本机端口:容器端口

小结

宿主机和容器拷贝文件
宿主机与容器共享文件
容器的网络模式
宿主机和容器的网络互通

7. Docker 实践

7.1 搭建私有仓库:Docker Registry

私有镜像仓库的解决方案(简单): Docker Registry

  1. 拉取镜像
docker pull registry
  1. 端口映射,暴露端口以提供服务
docker run -d -p 5000:5000 registry
  1. 使用 docker tag 命令给镜像打标签再上传到私有仓库

打标签

docker tag nginx:alpine 127.0.0.1:5000/nginx:alpine

上传

docker push 127.0.0.1:5000/nginx:alpine

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JLBsa3Ij-1693031721774)(img/私有仓库-打标签-上传.png)]

  1. 验证推送成功

删除后再拉取

docker rmi  127.0.0.1:5000/nginx:alpine
docker pull 127.0.0.1:5000/nginx:alpine

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-afhgsEc6-1693031721775)(img/私有仓库-验证推送成功.png)]

  1. 获取镜像列表

Docker Registry 提供了 RESTful API 来查看仓库中的镜像,具体 API 查看官方文档

分别获取了镜像列表和 Nginx 镜像的标签列表:

curl 127.1:5000/v2/_catalog
curl 127.1:5000/v2/nginx/tags/list

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2EB8Uqyz-1693031721775)(img/私有仓库-获取镜像列表.png)]

7.2 搭建 WordPress 网站

  1. 录取镜像

需要使用的镜像wordpressmariadbnginx

docker pull wordpress:5
docker pull mariadb:10
docker pull nginx:alpine
  1. 启动 MariaDB

配置“MARIADB_DATABASE”等几个环境变量,用 --env 参数来指定启动时的数据库、用户名和密码

docker run -d --rm \
    --env MARIADB_DATABASE=db \
    --env MARIADB_USER=wp \
    --env MARIADB_PASSWORD=123 \
    --env MARIADB_ROOT_PASSWORD=123 \
    mariadb:10

查看容器的 IP 地址:

docker inspect 9ac |grep IPAddress
  1. 运行应用服务器 WordPress
docker run -d --rm \
    --env WORDPRESS_DB_HOST=172.17.0.2 \
    --env WORDPRESS_DB_USER=wp \
    --env WORDPRESS_DB_PASSWORD=123 \
    --env WORDPRESS_DB_NAME=db \
    wordpress:5

查看容器的 IP 地址,方便 Nginx 进行反向代理的配置,假设为172.17.0.3

  1. 运行 Nginx

在当前文件夹下,编写 nginx 配置文件wp.conf

server {
  listen 80;
  default_type text/html;
  location / {
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      proxy_pass http://172.17.0.3;
  }
}

运行 Nginx:

docker run -d --rm \
    -p 80:80 \
    -v `pwd`/wp.conf:/etc/nginx/conf.d/default.conf \
    nginx:alpine

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优化器调整策略

损失函数的作用是衡量模型输出与真实标签的差异。当我们有了这个loss之后,我们就可以通过反向传播机制得到参数的梯度,那么我们如何利用这个梯度进行更新参数使得模型的loss逐渐的降低呢? 优化器的作用 Pytorch的优化器: 管理并…

校对的力量:当专业遇上细节,文字焕发新生

在这个信息爆炸的时代,文字成为了我们传达思想、展现形象的重要工具。从新闻稿、政府材料到商业文档,其背后的准确性和专业性往往决定了信息传递的效果。而保证这一切的,就是细致入微的校对工作。 1.错别字与校对:细节之美 错别字…

单机MySQL的演进

2、单机MySQL的演进 我们当前处于大数据时代,大数据一般的数据库无法进行分析处理了!2006年发布了Hadoop 1、单机MySQL的年代 某知名购物网站最开始就是到国外购买的PHP网站,拿过来就能直接使用,到后来也改成了Java。早期网站的数…

【Flutter】Flutter 使用 just_audio 播放音频

【Flutter】Flutter 使用 just_audio 播放音频 文章目录 一、前言二、环境与版本信息三、安装和基本使用四、深入 just_audio五、实际业务中的用法六、完整示例七、总结 一、前言 今天,我要为你介绍一个非常实用的 Flutter 音频处理包——just_audio。这个包不仅功…

IDEA软件安装包分享

目录 一、软件简介 二、软件下载 一、软件简介 IntelliJ IDEA是一款流行的Java集成开发环境(IDE),由捷克软件开发公司JetBrains开发。它专为Java开发人员设计,提供了许多高级功能和工具,使得开发人员能够更高效地编写…

《深入理解Java虚拟机》读书笔记:运行时栈帧结构

代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步。 一、概述 在Java虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,这个概念模型成为各种虚拟机执行引擎的统一外观(Facade&#x…

FrameWork之旅 -- Android_input浅析

最近工作超级忙,周末了,看了下博客,今年居然没有更新过博客,看来还是搬砖太忙了。通过3个小时的代码梳理后,下图是个人对input的简单分析,后面如果有精力,会有更新。

AcWing算法提高课-5.5.1可见的点

宣传一下 算法提高课整理 CSDN个人主页:更好的阅读体验 原题链接 题目描述 在一个平面直角坐标系的第一象限内,如果一个点 ( x , y ) (x,y) (x,y) 与原点 ( 0 , 0 ) (0,0) (0,0) 的连线中没有通过其他任何点,则称该点在原点处是可见的。…

第一个react应用程序并添加样式

编写第一个react应用程序 将目录下的文件、src文件夹、public文件夹清空&#xff0c;项目根目录下新建一个文件index.js 在文件中写入以下代码 import React from react import ReactDOM from react-dom ReactDOM.render(<h1>欢迎进入React的世界</h1>,document.…

【LeetCode-中等题】54. 螺旋矩阵

文章目录 题目方法一&#xff1a;按层模拟 题目 方法一&#xff1a;按层模拟 思路就是定义四个指针边界&#xff0c;按顺序扫完一遍&#xff0c;再缩小区域再扫描 public List<Integer> spiralOrder(int[][] matrix) {List<Integer> order new ArrayList<Int…

【IO进程线程】使用标准IO函数完成用户的登录和注册

1 实现登录功能 自定义一个usr.txt&#xff0c;先手动输入其账户密码。 格式&#xff1a;账户 密码 例&#xff1a; zhangsan 12345 lisi abcde wangwu abc123 需求如下&#xff1a; 1. 从终端获取账户密码&#xff0c;与文件中的账户密码比较&#xff1b; 2. 若终端输入的账户…

胖小酱之麻雀虽小

麻雀虽小&#xff0c;五脏俱全的意思&#xff1a;比喻事物的体积或规模虽小&#xff0c;具备的内容却很齐全。释义&#xff1a;比喻事物体积或规模虽小&#xff0c;具备的内容却很齐全。出处&#xff1a;茹志娟《如愿》&#xff1a;你别看我们那个生产小组不大&#xff0c;麻雀…

web自动化框架:selenium学习使用操作大全(Python版)

目录 一、浏览器驱动下载二、selenium-python安装&#xff08;打开网站、操作元素&#xff09;三、网页解析&#xff08;HTML、xpath&#xff09;四、selenium基本操作1、元素定位八种方法2、元素动态定位3、iframe切换4、填充表单_填充文本框5、填充表单_单选按钮6、填充表单_…

XGBoost,LightGBM

目录 XGBoost LightGBM Boosting 框架的主流集成算法&#xff0c;包括 XGBoost 和 LightGBM。 送上完整的思维导图&#xff1a; XGBoost XGBoost 是大规模并行 boosting tree 的工具&#xff0c;它是目前最快最好的开源 boosting tree 工具包&#xff0c;比常见的工具包快 1…

如何将多个网页合并成一个PDF文件?

pdfFactory是一款PDF虚拟打印软件&#xff0c;但与其他虚拟打印机软件不同的是&#xff0c;它使用起来更加简单高效。由于无需Acrobat就能生成Adobe PDF文件&#xff0c;它可以帮助用户在系统没有连接打印机的情况下&#xff0c;将大部分支持打印的文档资料迅速转换成PDF文件&a…

代码随想录第29天|491.递增子序列,46.全排列,47.全排列II

491.递增子序列 491. 递增子序列 这道题的特点是有序的子序列(不能对原数组排序)&#xff0c;最终结果集res不能有重复子集。所以这道题又是子集又是去重 回溯三部曲 1.递归函数参数 本题求子序列&#xff0c;很明显一个元素不能重复使用&#xff0c;所以需要startIndex&a…

无人机自主飞行实战入门-第一课(简介)

研究的意义&#xff1a;对人类操作的严重依赖&#xff0c;严重阻碍了泛无人机行业的发展。 飞行汽车&#xff08;UAM&#xff09;即将到来&#xff0c;不论是从成本还是安全考虑都需要自主飞行。 传统飞控基于STM32架构设计&#xff0c;无法满足更智能功能所需的计算量&#xf…

机器学习简介[01/2]:简单线性回归

Python 中的机器学习简介&#xff1a;简单线性回归 一、说明 简单线性回归为机器学习提供了优雅的介绍。它可用于标识自变量和因变量之间的关系。使用梯度下降&#xff0c;可以训练基本模型以拟合一组点以供未来预测。 二、技术背景 这是涵盖回归、梯度下降、分类和机器学习的其…

QT概括-Rainy

Qt 虽然经常被当做一个 GUI 库&#xff0c;用来开发图形界面应用程序&#xff0c;但这并不是 Qt 的全部&#xff1b;Qt 除了可以绘制漂亮的界面&#xff08;包括控件、布局、交互&#xff09;&#xff0c;还包含很多其它功能&#xff0c;比如多线程、访问数据库、图像处理、音频…

为Android做一个ShowModal窗口

大家知道&#xff0c;用Delphi实现一个Form&#xff0c;并用ShowModal显示出来&#xff0c;在Android平台是非阻塞的&#xff0c;即执行了Form.ShowModal&#xff0c;代码会继续往下执行而不是等待&#xff0c;这跟在Windows平台是完全不一样的。如果我们需要类似阻塞的效果&am…