【Flutter】篇9:相机

2023-11-09

挑选系统的相册,调用相机的功能,需要用到官网插件image_picker

官网代码

【运行报错】

ERROR:D8: Cannot fit requested classes in a single dex file (# methods: 68998 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
The number of method references in a .dex file cannot exceed 64K.

【解决】
启动MultiDex
【怎么启动】

  1. 如果您的 minSdkVersion 为 21 或更高版本,系统会默认启用 MultiDex,并且您不需要 MultiDex 库
    在 根目录/app/src/main/AndroidManifest.xml更改即可
    在这里插入图片描述

官网代码

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';

class MyImagePicker extends StatelessWidget {
  const MyImagePicker({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Image Picker Demo',
      home: MyHomePage(title: 'Image Picker Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<XFile>? _imageFileList;

  void _setImageFileListFromFile(XFile? value) {
    _imageFileList = value == null ? null : <XFile>[value];
  }

  dynamic _pickImageError;
  bool isVideo = false;

  VideoPlayerController? _controller;
  VideoPlayerController? _toBeDisposed;
  String? _retrieveDataError;

  final ImagePicker _picker = ImagePicker();
  final TextEditingController maxWidthController = TextEditingController();
  final TextEditingController maxHeightController = TextEditingController();
  final TextEditingController qualityController = TextEditingController();
  //取得视频的资源之后进行视频的播放
  Future<void> _playVideo(XFile? file) async {
    if (file != null && mounted) {
      await _disposeVideoController();
      late VideoPlayerController controller;
      if (kIsWeb) {
        controller = VideoPlayerController.network(file.path);
      } else {
        controller = VideoPlayerController.file(File(file.path));
      }
      _controller = controller;
      // In web, most browsers won't honor a programmatic call to .play
      // if the video has a sound track (and is not muted).
      // Mute the video so it auto-plays in web!
      // This is not needed if the call to .play is the result of user
      // interaction (clicking on a "play" button, for example).
      //控制视频的播放
      const double volume = kIsWeb ? 0.0 : 1.0;
      await controller.setVolume(volume);
      await controller.initialize();
      await controller.setLooping(true);
      await controller.play();
      setState(() {});
    }
  }
  /**点击右侧浮游按钮的处理方法
   * */
  Future<void> _onImageButtonPressed(ImageSource source,
      {BuildContext? context, bool isMultiImage = false}) async {
    if (_controller != null) {
      await _controller!.setVolume(0.0);
    }
    //处理Video
    if (isVideo) {
      //调用插件方法
      final XFile? file = await _picker.pickVideo(
          source: source, maxDuration: const Duration(seconds: 10));
      await _playVideo(file);
    }
    //处理多张照片
    else if (isMultiImage) {
      await _displayPickImageDialog(context!,
              (double? maxWidth, double? maxHeight, int? quality) async {
            try {
              //调用插件方法
              final List<XFile>? pickedFileList = await _picker.pickMultiImage(
                maxWidth: maxWidth,
                maxHeight: maxHeight,
                imageQuality: quality,
              );
              setState(() {
                _imageFileList = pickedFileList;
              });
            } catch (e) {
              setState(() {
                _pickImageError = e;
              });
            }
          });
    }
    //处理一张照片
    else {
      await _displayPickImageDialog(context!,
              (double? maxWidth, double? maxHeight, int? quality) async {
            try {
              final XFile? pickedFile = await _picker.pickImage(
                source: source,
                maxWidth: maxWidth,
                maxHeight: maxHeight,
                imageQuality: quality,
              );
              setState(() {
                _setImageFileListFromFile(pickedFile);
              });
            } catch (e) {
              setState(() {
                _pickImageError = e;
              });
            }
          });
    }
  }

  @override
  void deactivate() {
    if (_controller != null) {
      _controller!.setVolume(0.0);
      _controller!.pause();
    }
    super.deactivate();
  }

  @override
  void dispose() {
    _disposeVideoController();
    maxWidthController.dispose();
    maxHeightController.dispose();
    qualityController.dispose();
    super.dispose();
  }

  Future<void> _disposeVideoController() async {
    if (_toBeDisposed != null) {
      await _toBeDisposed!.dispose();
    }
    _toBeDisposed = _controller;
    _controller = null;
  }
  //中间的提示文字
  Widget _previewVideo() {
    final Text? retrieveError = _getRetrieveErrorWidget();
    if (retrieveError != null) {
      return retrieveError;
    }
    if (_controller == null) {
      return const Text(
        'You have not yet picked a video',
        textAlign: TextAlign.center,
      );
    }
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: AspectRatioVideo(_controller),
    );
  }
//中间的提示文字
  Widget _previewImages() {
    final Text? retrieveError = _getRetrieveErrorWidget();
    if (retrieveError != null) {
      return retrieveError;
    }
    if (_imageFileList != null) {
      return Semantics(
        label: 'image_picker_example_picked_images',
        child: ListView.builder(
          key: UniqueKey(),
          itemBuilder: (BuildContext context, int index) {
            // Why network for web?
            // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform
            return Semantics(
              label: 'image_picker_example_picked_image',
              child: kIsWeb
                  ? Image.network(_imageFileList![index].path)
                  : Image.file(File(_imageFileList![index].path)),
            );
          },
          itemCount: _imageFileList!.length,
        ),
      );
    } else if (_pickImageError != null) {
      return Text(
        'Pick image error: $_pickImageError',
        textAlign: TextAlign.center,
      );
    } else {
      return const Text(
        'You have not yet picked an image.',
        textAlign: TextAlign.center,
      );
    }
  }
  //对中间提示文字进行了一次封装
  Widget _handlePreview() {
    if (isVideo) {
      return _previewVideo();
    } else {
      return _previewImages();
    }
  }

  Future<void> retrieveLostData() async {
    final LostDataResponse response = await _picker.retrieveLostData();
    if (response.isEmpty) {
      return;
    }
    if (response.file != null) {
      //如果是video
      if (response.type == RetrieveType.video) {
        isVideo = true;
        await _playVideo(response.file);
      }
      //是图片
      else {
        isVideo = false;
        setState(() {
          if (response.files == null) {
            _setImageFileListFromFile(response.file);
          } else {
            _imageFileList = response.files;
          }
        });
      }
    } else {
      _retrieveDataError = response.exception!.code;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // appBar: AppBar(
      //   title: Text(widget.title!),
      // ),
      body: Center(
        child: !kIsWeb && defaultTargetPlatform == TargetPlatform.android
            ? FutureBuilder<void>(
          future: retrieveLostData(),//以后呈现的widget?
          builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
              case ConnectionState.waiting:
                return const Text(
                  'You have not yet picked an image.',
                  textAlign: TextAlign.center,
                );
              case ConnectionState.done:
                return _handlePreview();
              default:
                if (snapshot.hasError) {
                  return Text(
                    'Pick image/video error: ${snapshot.error}}',
                    textAlign: TextAlign.center,
                  );
                } else {
                  return const Text(
                    'You have not yet picked an image.',
                    textAlign: TextAlign.center,
                  );
                }
            }
          },
        )
            : _handlePreview(),
      ),
      /**右侧的浮游按钮*/
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Semantics(//给UI加上语义,对一些语法分析器或者搜索引擎有帮助
            label: 'image_picker_example_from_gallery',
            child: FloatingActionButton(
              onPressed: () {
                isVideo = false;
                _onImageButtonPressed(ImageSource.gallery, context: context);
              },
              heroTag: 'image0',
              tooltip: 'Pick Image from gallery',
              child: const Icon(Icons.photo),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              onPressed: () {
                isVideo = false;
                _onImageButtonPressed(
                  ImageSource.gallery,
                  context: context,
                  isMultiImage: true,
                );
              },
              heroTag: 'image1',
              tooltip: 'Pick Multiple Image from gallery',
              child: const Icon(Icons.photo_library),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              onPressed: () {
                isVideo = false;
                _onImageButtonPressed(ImageSource.camera, context: context);
              },
              heroTag: 'image2',
              tooltip: 'Take a Photo',
              child: const Icon(Icons.camera_alt),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              backgroundColor: Colors.red,
              onPressed: () {
                isVideo = true;
                _onImageButtonPressed(ImageSource.gallery);
              },
              heroTag: 'video0',
              tooltip: 'Pick Video from gallery',
              child: const Icon(Icons.video_library),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              backgroundColor: Colors.red,
              onPressed: () {
                isVideo = true;
                _onImageButtonPressed(ImageSource.camera);
              },
              heroTag: 'video1',
              tooltip: 'Take a Video',
              child: const Icon(Icons.videocam),
            ),
          ),
        ],
      ),
    );
  }

  Text? _getRetrieveErrorWidget() {
    if (_retrieveDataError != null) {
      final Text result = Text(_retrieveDataError!);
      _retrieveDataError = null;
      return result;
    }
    return null;
  }

  Future<void> _displayPickImageDialog(
      BuildContext context, OnPickImageCallback onPick) async {
    return showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('Add optional parameters'),
            content: Column(
              children: <Widget>[
                TextField(
                  controller: maxWidthController,//该变量存储输入内容的值
                  keyboardType:
                  const TextInputType.numberWithOptions(decimal: true),
                  decoration: const InputDecoration(
                      hintText: 'Enter maxWidth if desired'),
                ),
                TextField(
                  controller: maxHeightController,
                  keyboardType:
                  const TextInputType.numberWithOptions(decimal: true),
                  decoration: const InputDecoration(
                      hintText: 'Enter maxHeight if desired'),
                ),
                TextField(
                  controller: qualityController,
                  keyboardType: TextInputType.number,
                  decoration: const InputDecoration(
                      hintText: 'Enter quality if desired'),
                ),
              ],
            ),
            actions: <Widget>[
              TextButton(
                child: const Text('CANCEL'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
              TextButton(
                  child: const Text('PICK'),
                  onPressed: () {
                    final double? width = maxWidthController.text.isNotEmpty
                        ? double.parse(maxWidthController.text)
                        : null;
                    final double? height = maxHeightController.text.isNotEmpty
                        ? double.parse(maxHeightController.text)
                        : null;
                    final int? quality = qualityController.text.isNotEmpty
                        ? int.parse(qualityController.text)
                        : null;
                    onPick(width, height, quality);
                    Navigator.of(context).pop();
                  }),
            ],
          );
        });
  }
}

typedef OnPickImageCallback = void Function(
    double? maxWidth, double? maxHeight, int? quality);

class AspectRatioVideo extends StatefulWidget {
  const AspectRatioVideo(this.controller, {Key? key}) : super(key: key);

  final VideoPlayerController? controller;

  @override
  AspectRatioVideoState createState() => AspectRatioVideoState();
}

class AspectRatioVideoState extends State<AspectRatioVideo> {
  VideoPlayerController? get controller => widget.controller;
  bool initialized = false;

  void _onVideoControllerUpdate() {
    if (!mounted) {
      return;
    }
    if (initialized != controller!.value.isInitialized) {
      initialized = controller!.value.isInitialized;
      setState(() {});
    }
  }

  @override
  void initState() {
    super.initState();
    controller!.addListener(_onVideoControllerUpdate);
  }

  @override
  void dispose() {
    controller!.removeListener(_onVideoControllerUpdate);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (initialized) {
      return Center(
        child: AspectRatio(
          aspectRatio: controller!.value.aspectRatio,
          child: VideoPlayer(controller!),
        ),
      );
    } else {
      return Container();
    }
  }
}

效果图

主页面
在这里插入图片描述
挑选一张照片
在这里插入图片描述
正在播放视频
在这里插入图片描述

知识点补充

  1. Future:Dart的异步对象,类似于JavaScript中的Promise
    1. 是一个异步操作返回的结果
    2. 是一个泛型类
    3. 官网说明在这里插入图片描述

  1. 在这里插入图片描述
    Dart中的?学问:博客
    1. String?name :表示可空类型
    2. String a = b ?? ‘hello’:b不为空,a赋值为b。b为Null,则a赋值为‘hello’
    3. b ??= ‘hello’:如果b为null则赋值为hello,否则不会改动
    4. a?.p a?.m():如果a为空,则直接返回Null,不执行后面的操作
      2. a!.p 断言,表示a肯定不为null
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Flutter】篇9:相机 的相关文章

  • Android:动态更改Listview中的图像

    我有一个由以下 xml 定义的列表视图 我需要切换图像当用户单击任何行时 在运行时会出现在列表中 我怎样才能实现这个目标 非常感谢任何帮助 谢谢 list item xml
  • 在 Android 中从互联网链接获取数据

    我正在制作一个带有 URL 的应用程序 asp 扩展名 我们向其传递所需的参数并使用 POST 方法获取一些字符串结果 关于如何实现这一目标有什么建议吗 UPDATED 实际上我有一个 net 链接 它接受一些 POST 参数并给我一个结果
  • 在 Android 上检测已接听的拨出电话

    我知道这个问题已经被问过很多次了 但没有答案 但我仍然希望有人终于解决了这个问题 问题 我有一台运行 Android 2 3 的未 root 设备 我需要创建一项服务 打电话 等待呼叫被应答 接听电话后挂断电话 有超时 和其他许多人一样 我
  • 读取 Android 4.2 中的 APN?

    我有个问题阅读 APN在安卓v4 2中 是读 不是写APNS 它抛出一个安全异常 没有写入 APN 设置的权限 用户 10068 和当前用户都没有权限 进程有 android permission WRITE APN SETTINGS 相同
  • Android 测试 java.lang.NoClassDefFoundError 由于 Fest-Android 出现错误

    我目前正在我的项目中实现 Android 版 Fest 但我似乎遇到了依赖问题 如果我在不包含 Fest 库的情况下运行测试 测试将正常运行 一旦我添加了 Fest 库 测试就不再运行 相反 会抛出异常 我的项目使用以下依赖项 compil
  • Android 服务 START_STICKY START_NOT_STICKY

    我需要让我的服务始终在后台运行 并使用 startService 函数启动我的服务 无论应用程序的状态如何 我都不想重新启动服务 这是我的观察 START STICKY gt 如果应用程序启动 则服务正在重新启动 当应用程序关闭时 服务也会
  • 带有内容提供商的小部件;无法使用ReadPermission?

    所以我刚刚为我的应用程序实现了一个小部件 它通过我的数据库从数据库获取数据ContentProvider 我在清单中定义了自己的读 写权限 声明我使用它们 似乎没有什么区别 并在内容提供程序中要求它们
  • 具有多个字符串的列表视图

    我正在尝试创建一个包含多个字符串的列表视图 现在我有一个可以实现的功能 while i lt 10 GETS DATA FROM WEBPAGE ETC a DATAFROMWEBPAGE1 b DATAFROMWEBPAGE2 c DAT
  • Android Studio 停留在构建 gradle 项目信息上

    我正在使用 Android Studio 2 3 每当我尝试创建一个新项目或打开某个项目时 它都会卡在此时 正在构建 Gradle 项目信息 请建议我一些解决方案 它可能正在下载 Gradle zip 文件 e g Users user g
  • Eclipse Android 模拟器 - 键盘不工作

    我刚刚更新到最新的 SDK 版本 16 使用最新版本的 API 16 创建了新版本的 AVD 并且我的硬件键盘在模拟器上不再工作 甚至我的其他 avd 使用旧版本的 sdk 任何想法如何解决这一问题 您的 AVD 的 键盘支持 硬件属性是否
  • 谷歌的Json解析Gson库:JsonElement和JsonObject有什么区别?

    public abstract class JsonElement extends Object 表示 Json 元素的类 它可以是 JsonObject JsonArray JsonPrimitive 或 JsonNull public
  • 应用程序运行时相对布局中的元素显示不同

    我有一个ListView在片段内创建 并且它有一个搜索过滤器 问题是 XML 布局在 android studio 中显示正常 但在模拟器或手机中运行时 它显示不同 与我对齐时不正确 并且当我单击SearchView它位于选项卡导航下方 谁
  • 尝试重新打开已关闭的对象:sqlitequery

    所以本质上我查询数据库两次 我不明白这个错误真正来自哪里 因为我没有在任何地方关闭数据库 返回错误的代码是这样运行的 我查了一下 刚刚看到一个像我这样的案例 BeaconHandler pullAllDB new BeaconHandler
  • 如何在 Android 中不使用 Intent 裁剪图像

    我正在尝试裁剪图像我使用了下面的代码 意图 i new Intent Intent ACTION PICK android provider MediaStore Images Media EXTERNAL CONTENT URI i pu
  • 使用Android Camera API,拍摄照片的方向始终未定义

    我使用相机API 拍摄的照片总是旋转90度 我想旋转它 所以首先我想知道图片的方向 这一点我被卡住了 我总是以两种方式得到未定义的方向 这是代码 Override public void onPictureTaken byte data C
  • 如何以相同的意图从相机获取全尺寸图片和缩略图

    我一直需要找到这个问题的解决方案 我已经从这个社区搜索并测试了许多解决方案 但任何人都适合帮助我 我有两个活动 第一个活动拍摄一张照片并将其发送到另一个活动 该活动有一个 ImageView 来接收该照片 直到这里我遇到问题 以及一个在数据
  • Flutter 导航到其他页面中的特定选项卡

    我正在尝试从一个页面导航到另一页面并设置选项卡栏的索引 这是我在第一页的代码 GestureDetector onTap Navigator push context MaterialPageRoute builder context gt
  • Android 布局仅使一个视图将自己绘制为横向,但其他所有视图都使用纵向

    我的活动布局中的主要视图元素是 VideoView 我的视频被渲染为设备的横向分辨率 但视频中的所有内容都是横向的 因此仍然需要在设备处于纵向位置时观看 即使我必须将活动设置为android screenOrientation landsc
  • 在自定义对话框中设置文本视图

    我创建了一个自定义对话框 但无法将文本设置到 java 对话框布局中的文本视图中 并且我的程序崩溃了 我的错误是什么 public class Total CBC extends Activity Override protected vo
  • 带有包含布局的导航抽屉布局

    我认为我的问题实际上很简单 但我不知道如何解决 有一个工作导航抽屉 代码如下

随机推荐

  • top5数据高级分析必备的Python库

    top5数据高级分析必备的Python库 1 Pandas 2 Numpy 3 Matplotlib https blog csdn net qq 40985985 article details 119676953 4 Scikit 学习
  • 【 Python 全栈开发 - 语法基础篇 - 19 】模块和包

    文章目录 一 模块 二 包 在 Python 中 模块指的是一个包含 Python 代码的文件 它可以被其他 Python 程序导入和使用 模块通常包括一些函数 类和变量 可以用于执行特定的任务或实现特定的功能 而包指的是一个包含多个模块的
  • 抖音短视频矩阵系统多账号管理,功能框架及开发逻辑

    目录 文章目录 前言 一 矩阵号系统是什么 二 使用步骤 1 创建推广项目 2 多账号授权 3 企业号智能客服系统 总结 前言 短视频多账号矩阵系统 通过多账号一键授权管理的方式 为运营人员打造功能强大及全面的 矩阵式 管理平台 使用矩阵系
  • MOS管、BJT 饱和区 不同

    1 深刻理解并记住工作在开关状态下 两种器件工作在何种工作区 三极管 从左到右 依次为 饱和 放大 截至 开关状态下是工作在截至与饱和区之间 MOS 从左到右 依次为可变电阻 非饱和区 完全导通区 饱和 横流区 放大区 有源区 线性区 截至
  • Vue3报错Property “xxx“ was accessed during render but is not defined on instance.

    使用Vue3重构自己项目时遇到报错 Property xxx was accessed during render but is not defined on instance 碰到这个报错已经不是一次两次了 写篇文章记录一下 翻译 Pro
  • 软件缺陷的管理

    目录 1 软件缺陷产生的原因 1 1 需求不明确 1 2 软件结构复杂 1 3 编码问题 1 4 项目期限太短 1 5 使用新技术 2 软件缺陷的分类 2 1 从测试种类划分缺陷 2 2 从缺陷严重程度划分 2 3 从缺陷的优先级划分 2
  • 【计算机视觉

    文章目录 一 检测相关 18篇 1 1 Neural Network Training Strategy to Enhance Anomaly Detection Performance A Perspective on Reconstru
  • Ubuntu更换源-清华大学源

    文章目录 前言 备份原来的源 更换源 更新源 前言 安装好ubuntu系统后 默认的软件更新源是国外的 在国内使用速度很慢 安装软件时可能出现 各种各样的错误 所以我们需要更换成国内的源 这样才能更快更安全的安装和更新软件 此次我们选用的是
  • scratch 鼠标控制角色移动

    scratch 鼠标控制角色 本程序使用鼠标操作 机器人 角色跟随鼠标 距离较小时暂停移动 小狗 角色连续在随机位置生成 水平移动 碰到边缘反弹 碰到 机器人 角色时删除 目前scratch程序的制作已经告一段落了 进一步开发需要更多规划
  • 多路ADC的采集——stm32

    在对实际应用过程中 ADC的采集大多是多个通道同时采集的 比如同时采集多个传感器的数据 就可能需要我们配置多个通道的ADC采集了 而多通道的ADC采集大多用到了DMA 笼统的讲通过DMA来传输数据不经过CPU 可以有效的为CPU减负 我们在
  • Linux开发工具

    目录 Linux 软件包管理器 yum 如何安装软件 如何卸载软件 Linux编辑器 vim使用 1 vim的基本概念 2 vim的基本操作 3 vim正常模式命令集 4 vim末行模式命令集 5 vim操作总结 7 一些小指令 Linux
  • TypeError:__init__() got an unexpected keyword argument ‘xxx‘

    检查一下通常是某个关键字打错了
  • 排序算法:冒泡排序

    基本思想 相邻的两个元素进行比较 按照要求进行交换 思路 以升序为例 进行第一趟排序 第一个元素和第二个元素进行比较 将较大的放在第二个元素的位置上 然后第二个和第三个元素进行比较 将较大的放在第三个元素的位置上 依次类推 直到 第一趟排序
  • 2023.05-B卷-华为OD机试 - 阿里巴巴找黄金宝箱(I)-”新加题型“(100分值)

    www codefun2000 com 最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据 挂载到我们的OJ上 供大家学习交流 体会笔试难度 现已录入200 道互联网大厂模拟练习题 还在极速更新中 欢迎关注公众号 塔子哥学算
  • 提高代码质量之静态代码检查

    http www jianshu com p 2b8d34b2267c 前言 在团队Android项目开发过程中 难免会出现一些比较不容易发现 但是又比较低级的bug 而且因为每个开发人员的编码习惯不同 写出的代码也会有差异 为了保证团队开
  • Java小程序简易多客户端聊天服务器

    前言 最近在上JAVA课时学习了多线程有关知识 结合之前的练习 自己试着写了个多客户端聊天器 现放在这里 希望能对各位同袍有所帮助 注意为了防止抄袭 以下仅放出Client和Server部分 对于信息部分没有发上来 不过主要难点都在已发上来
  • 【项目设计】高并发内存池(五)[释放内存流程及调通]

    C 学习历程 入门 博客主页 一起去看日落吗 持续分享博主的C 学习历程 博主的能力有限 出现错误希望大家不吝赐教 分享给大家一句我很喜欢的话 也许你现在做的事情 暂时看不到成果 但不要忘记 树 成长之前也要扎根 也要在漫长的时光 中沉淀养
  • (算法)从10000个数中找出最大的10个

    从10000个整数中找出最大的10个 最好的算法是什么 算法一 冒泡排序法 千里之行 始于足下 我们先不说最好 甚至不说好 我们只问 如何 从10000个整数中找出最大的10个 我最先想到的是用冒泡排序的办法 我们从头到尾走10趟 自然会把
  • Vue3+TypeScript+Router+Vuex+Ant-Design-Vue项目(一)—— 使用 vue-cli 搭建项目

    为了更好地掌握 vue3 和 TypeScript 准备搭建一个后台管理系统来学习一下 技术栈 Vue3 Typescript Vue router Vuex Ant Design Vue 1 初始化项目 vue create
  • 【Flutter】篇9:相机

    挑选系统的相册 调用相机的功能 需要用到官网插件image picker 官网代码 运行报错 ERROR D8 Cannot fit requested classes in a single dex file methods 68998