自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

洪伟的专栏

长兄于病视神,未有形而除之,故名不出于家。中兄治病,其在毫毛,故名不出于闾。若扁鹊者,镵血脉,投毒药,副肌肤,闲而名出闻于诸侯。

  • 博客(134)
  • 资源 (10)
  • 收藏
  • 关注

原创 Android 源码 Wi-Fi 连接流程分析

Wi-Fi 连接过程可以从 Settings App 中点击任意 Wi-Fi 条目连接说起。点击条目以后会弹出一个对话框,根据不同的 Wi-Fi 类型需要填入必要的信息,再点击连接按钮,发起连接过程。点击 Dialog 上的按钮会路由到 WifiDialog.BUTTON_SUBMIT 分支,如果是已经连接成功的 Wi-Fi 则路由到 WifiDialog.BUTTON_FORGET 分支。WifiDialog.BUTTON_SUBMIT 分支进一步调用了 submit(…) 方法。submit(…)

2021-01-04 18:39:10 59

原创 Android app 首次运行违规读取 Mac 地址定位方法

通常意义上来说,app 可以读取 mac 地址,但仅限于用户已经阅读了隐私内容,并且隐私内容中也告知了用户,app 会运行期间采集 wlan mac 地址等信息。所以如果没等用户同意隐私政策中的内容,就开始提前读取 mac 地址,这是不合法的行为。工信部抽查中如果发现此类行为,app 会被通告整改,整改不力的将强制从应用市场下架,后果还是很严重的。但这里忽略一个问题,如果我们的 app 本身代码没有读取 mac 地址,那如何是好?自己的代码心中有数,实在不行可以全局搜索,如果第三方库偷偷摸摸的读取 mac

2020-12-17 06:20:28 497

原创 使用 freeradius 搭建 EAP PEAP MS-CHAPv2 验证环境

企业级 Wi-Fi 搭建起来有点小复杂,我们知道自己家使用的 Wi-Fi 非常简单,几乎只需要配置一下热点的 SSID 和密码就可以了,实际上这是两种 Wi-Fi 认证类型。想要快速部署企业级 Wi-Fi 验证环境,首先要理解企业级 Wi-Fi 部署的一些核心组件以及相应的协议。一、Wi-Fi 认识Wi-Fi(发音:/ˈwaɪfaɪ/,法语发音:/wifi/),在中文里又称作“行动热点”,是 Wi-Fi 联盟制造商的商标做为产品的品牌认证,是一个创建于 IEEE 802.11 标准的无线局域网技术。基于

2020-12-16 19:35:40 286

原创 Android 源码 Camera2 预览流程分析四

《Android 源码 Camera2 预览流程分析二》中进行了流启动,这是调用 QCamera3Channel start() 方法实现的,对应于 HAL_PIXEL_FORMAT_YCbCr_420_888 格式创建的 QCamera3Channel 实现类指向了 QCamera3RegularChannel。device/moto/shamu/camera/QCamera2/HAL3/QCamera3Channel.cppint32_t QCamera3RegularChannel::start

2020-12-10 07:55:45 83

原创 Android 源码 Camera2 预览流程分析三

接着《Android 源码 Camera2 预览流程分析二》,先来分析 QCamera3Channel 初始化,通过《Android 源码 Camera2 HAL3 流配置》一节可以知道实际上 对应于 HAL_PIXEL_FORMAT_YCbCr_420_888 格式创建的 QCamera3Channel 实现类指向了 QCamera3RegularChannel。调用 init(…) 初始化;确定流格式;调用 addStream(…) 添加流。device/moto/shamu/camera

2020-12-08 19:38:51 137

原创 Android 源码 Camera2 HAL3 流配置

HAL 流配置的起点位于 Camera3Device 类 configureStreamsLocked() 方法中,首先调用 configure_streams(…) 进行配置。frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cppstatus_t Camera3Device::configureStreamsLocked() { ...... // 做 HAL 配置 ATRACE_BEG

2020-12-01 20:02:47 297

原创 Android 源码 Camera2 预览流程分析二

RequestThread 是在 Camera open 流程中启动的。RequestThread 是用于管理向 HAL 设备提交捕获请求的线程。frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cppstatus_t Camera3Device::initialize(CameraModule *module){ ...... /** Start up request queue thread *

2020-11-30 19:29:57 140

原创 Android 源码 Camera2 预览流程分析一

先上一段典型的预览代码,梳理一下相机预览流程。从 TextureView 获取到 SurfaceTexture将 SurfaceTexture 默认缓冲区的大小配置为相机预览的大小新建一个 Surface 作为预览输出CaptureRequest.Builder 设置 Surface创建 CameraCaptureSession 用于相机预览创建成功 CameraCaptureSession 后给 CaptureRequest.Builder 设置自动对焦,必要时开启闪光灯现在可以开始显示相

2020-11-26 14:31:16 88

原创 WAV 音频格式学习

WAV 是最常见的声音文件格式之一,是微软公司专门为 Windows 开发的一种标准数字音频文件,该文件能记录各种单声道或立体声的声音信息,并能保证声音不失真。但 WAV 文件有一个致命的缺点,就是它所占用的磁盘空间太大。它符合资源互换文件格式(RIFF)规范,用于保存 Windows 平台的音频信息资源,被 Windows 平台及其应用程序所广泛支持。Wave 格式支持 MSADPCM、CCITT A 律、CCITT μ 律和其他压缩算法,支持多种音频位数、采样频率和声道,是 PC 机上最为流行的声音文件

2020-10-23 17:11:34 102

原创 Android 源码 Camera2 openCamera 流程分析

打开相机的起点从 CameraManager 类 openCamera(…) 方法开始。打开具有给定 ID 的相机连接。使用 getCameraIdList 获取可用相机设备的列表。请注意,即使列出了 ID,但如果在对 getCameraIdList 和 openCamera 的调用之间断开了设备的连接,或者如果优先级更高的相机 API 客户端开始使用相机设备,则打开可能会失败。从 API 级别 23 开始,由于优先级较低的后台相机 API 客户端正在使用该设备,因此已调用 Availability

2020-10-20 08:48:43 183

原创 Android 源码 Camera2 获取 CameraId 列表

获取 CameraId 列表通过调用 CameraManager 类 getCameraIdList() 实现。getCameraIdList() 按标识符返回当前连接的摄像头设备列表,包括其他 camera API 客户端可能正在使用的摄像头。不可移动摄像头的标识符使用以 0 开头的整数,而可移动摄像头即使是同一型号,也为每个设备都分配唯一的标识符。frameworks/base/core/java/android/hardware/camera2/CameraManager.javapubli

2020-09-24 08:43:10 1858

原创 Android 源码 QCamera2 HAL 分析

我们以 moto Nexus 6 device/moto/shamu/camera/QCamera2/ 为例进行分析。QCamera2Hal.cpp 中给 hw_module_t 结构体 camera_common 进行了赋值,然后又给 camera_module_t 结构体 HAL_MODULE_INFO_SYM 赋值,HAL_MODULE_INFO_SYM 名字是固定的,这样 hw_get_module(…) 函数才能正常工作。device/moto/shamu/camera/QCamera2/QCa

2020-09-20 15:20:46 342 4

原创 Android 源码 Camera2 CameraService 启动

CameraService 的起点需要从 init.rc 说起。解析 init.rc 脚本是在 init.cpp 入口方法 main 中开始解析的。mediaserver 服务进程随即就会启动。system/core/rootdir/init.rcservice media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct dr

2020-09-19 18:53:46 138

原创 Android 源码 Camera2 获取 CameraManager 对象

CameraManager 类是开放给 App 使用相机的入口类,它包括了获取相机 ID 列表、打开和关闭相机等操作,用于检测、表征和连接到 CameraDevice。下面是 APP 获取 CameraManager 类的代码。CAMERA_SERVICE 定义在 Context 中,CAMERA_SERVICE = “camera”。val manager = activity.getSystemService(Context.CAMERA_SERVICE) as CameraManager由于传

2020-08-30 20:18:46 175

原创 Android 源码 Camera2 架构初识

android.hardware.camera2 包为连接到 Android 设备的单个相机设备提供了接口。该包将相机设备建模为管道,它接收捕获单个帧的输入请求,捕获每个请求的单个图像,然后输出一个捕获结果元数据包,以及一组用于请求的输出图像缓冲区。请求按顺序处理,可以同时处理多个请求。由于相机设备是一个多阶段的管道,所以在大多数 Android 设备上,要保持完整的帧率需要有多个请求在运行。要枚举、查询和打开可用的相机设备,需要获取 CameraManager 实例。各个 CameraDevices

2020-08-30 20:14:29 778

原创 Android 源码 图形系统之 SurfaceFlinger 服务启动

SurfaceFlinger 服务起点在 init.rc 中。boot Action 中最后 class_start 命令启动了分类为 core 的所有服务,这其中就包括 surfaceflinger。system/core/rootdir/init.rcon boot ...... class_start core......service surfaceflinger /system/bin/surfaceflinger class core user syste

2020-08-18 21:00:01 872

原创 Android 源码 图形系统之创建 Layer

层 Layer 创建起点是 new 一个 Layer 对象,当对象第一次被引用的时候就会触发其 onFirstRef() 方法。Layer 构造器中初始化了一大堆成员变量。onFirstRef() 方法中看到了几个重量级选手,这里创建了 BufferQueue 和 SurfaceFlingerConsumer。Layer 类首次引用图层时,将创建新的 BufferQueue 和新的 SurfaceFlingerConsumer。它还实现了 onFrameAvailable(),该函数通知 Surfac

2020-08-18 20:57:23 100

原创 Android 源码 图形系统之 Surface 初始化

在 《Android 源码 图形系统之 relayoutWindow》 一节中,outSurface 初始化(调用其 copyFrom(…) 方法,入参是 SurfaceControl 对象)没有继续分析了。现在详细来分析一下后续流程。copyFrom(…) 方法将另一个 Surface 复制到此 Surface。现在,此 Surface 拥有对与原始 Surface 相同数据的引用,并且不是所有者。这是供窗口管理器从客户端返回窗口 Surface 时使用的,将其从窗口管理器管理的表示形式转换为客户端用来

2020-08-18 20:53:51 94

原创 Android 8.1 【FriendlyARM】读取 BMP180 温度和压力系统服务、APP 开发

上一节完成了 BMP180 HAL 开发,现在再来继续后续内容:Bmp180Service 服务开发、APP 开发和处理 SEAndroid。一、Bmp180Service 服务开发先到 frameworks/base/core/java/android/os 目录下新建 bmp180 目录,然后创建 Bmp180Manager.java、BMP180TemperatureAndPressure.java、BMP180TemperatureAndPressure.aidl 和 IBmp180Servic

2020-08-15 20:32:26 145

原创 Android 8.1 【FriendlyARM】读取 BMP180 温度和压力 HAL 开发

接上一节我们已经将 BMP180 驱动开发完成,现在继续完成 HAL 开发,Android 8 版本新增的 HAL 一般采用 binder 的方式,使用 HIDL 语言进行开发。实际开发除了代码完成,绕不开 SEAndroid。下面分几个步骤介绍。HAL 开发HAL 验证Bmp180Service 服务开发APP 开发处理 SEAndroid一、HAL 开发在 Android 8.0 及更高版本中,较低级别的层已重新编写以采用更加模块化的新架构。搭载 Android 8.0 或更高版本的设

2020-08-15 17:28:22 114

原创 Android 源码 图形系统之 relayoutWindow

在 《Android 源码 图形系统之请求布局》 一节,分析到 ViewRootImpl 类 performTraversals() 方法内调用 relayoutWindow(…) 方法重新布局窗口时没有继续进一步深入,现在从 relayoutWindow(…) 开始来梳理后续流程。ViewRootImpl 类 relayoutWindow(…) 方法内部最终调用了 Session 类 relayout(…) 方法。mWindowSession 指向相应的代理对象 IWindowSession.Stub.

2020-08-13 19:41:24 216

原创 Android 源码 图形系统之 WindowState attach

在 《Android 源码 图形系统之窗口添加》 一节中提到 WindowManagerService 类addWindow 方法首先创建了 WindowState 对象,然后调用了其 attach() 方法进行附着,现在继续分析其后续流程。WindowState 类 attach() 方法中仅仅调用了 Session 类的 windowAddedLocked() 方法。frameworks/base/services/core/java/com/android/server/wm/WindowSt

2020-08-06 21:42:49 125

原创 Android 源码 图形系统之硬件渲染器同步和绘制帧

在《Android 源码 图形系统之硬件渲染器绘制》一节中没有分析 nSyncAndDrawFrame(…) 同步和绘制帧,这一节继续分析。frameworks/base/core/java/android/view/ThreadedRenderer.javapublic class ThreadedRenderer extends HardwareRenderer { ...... @Override void draw(View view, AttachInfo attach

2020-07-19 16:47:47 848

原创 Android 8.1 【FriendlyARM】温度压力传感器-BMP180 驱动开发

驱动开发主要位于 Linux 内核层,首先认识一下 BMP180,接着需要修改 DTS,最后才开始编写驱动,编写完驱动我们再来写一个用户层验证程序来获取温度和压力。一、BMP180 芯片介绍BMP180 是一款高精度、小体积、超低能的压力传感器,适用于移动电话、PDAs、GPS 导航设备和户外设备。在与仅仅 0.25 米低空噪音快速转换时,BMP180 提供卓越的性能。使用 I2C 接口可以很轻松的跟主控制器系统进行通讯。BMP180 基于压阻式技术 EMC 稳健性、高精度以及线性长期稳定性,被设计用

2020-07-19 15:58:13 200

原创 Android 源码 图形系统之硬件渲染器绘制
原力计划

硬件渲染器绘制从调用 HardwareRenderer 类 draw 方法实现 View 绘制开始。frameworks/base/core/java/android/view/ViewRootImpl.javapublic final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks { ...... pr

2020-07-11 15:17:21 130

原创 Android 源码 图形系统之硬件渲染器初始化
原力计划

硬件渲染器初始化从 ViewRootImpl 类 setView(…) 方法中调用 enableHardwareAcceleration(…) 开始。HardwareRenderer 是一个抽象类,代表使用硬件加速渲染视图层次结构的接口。首先找到 mHardwareRenderer 赋值的位置,我们才能确认它具体是什么子类。这在 ViewRootImpl 类 setView 方法中调用 enableHardwareAcceleration(…) 方法启用硬件加速开始。frameworks/base/c

2020-07-11 15:14:41 127

原创 Android 源码部署到服务器(Git+GitLab+Repo)
原力计划

Android 源码部署到服务器端,一共分为七个部分。软件环境GitLab 服务端部署Repo Manifest.xml 生成GitLab 建仓Git Push 源码到服务器Repo 同步源码提交修改后的代码一、软件环境服务器端系统:Ubuntu 16.04GitLab 软件:GitLab Community Edition客户端系统:Ubuntu 14.04Git 软件:Git 2.27.0二、GitLab 服务端部署必要组件安装sudo apt-get update

2020-07-08 17:50:28 594 4

原创 Android 8.1 【FriendlyARM】编译环境搭建与镜像烧写
原力计划

NanoPC-T4 不仅是世界上最小的全功能接口 RK3399 一体化主板, 而且是一款完全开源的高性能计算平台。它的尺寸只有 100x64mm,标配4GB LPDDR3 内存和 16GB 闪存, 板载2.4G & 5G 双频 WiFi 模组, 带有标准完整的 M.2 PCIe 接口, 可直接安装使用 NVME SSD 高速固态硬盘。NanoPC-T4 还带有 MIPI-CSI 双摄像头接口, MIPI-DSI 和 eDP 双显示接口, HDMI 2.0 视频输出口,并具备 Type-C/DP,U

2020-07-05 20:26:14 600

原创 Android 源码 图形系统之请求布局
原力计划

在《Android 源码 图形系统之窗口添加》一节中遗留了 ViewRootImpl 类 setView 方法中调用 requestLayout() 函数分析。现在继续分析其流程。分析之前先来观摩一下整体流程。requestLayout() 方法主要调用了 scheduleTraversals() 进一步处理。frameworks/base/core/java/android/view/ViewRootImpl.javapublic final class ViewRootImpl implemen

2020-07-05 09:55:18 150

原创 Android 源码 图形系统之窗口添加
原力计划

《Android 源码 输入系统之窗口关联》 一节着重考虑了窗口怎样和输入系统关联,而这一节的重点在于窗口如何添加到图形系统。先来看一个整体概览,再来详细分析。先从 setContentView 说起。此函数的作用是:从布局资源设置 Activity 内容。资源将被解析,将所有顶级视图添加到 Activity 中。首先调用 getWindow() 获取 Window 对象(实际为 PhoneWindow 对象),然后调用其 setContentView(…) 方法。frameworks/base/c

2020-06-26 19:06:15 149

原创 Android 源码 图形系统概述
原力计划

Android 框架提供了各种用于 2D 和 3D 图形渲染的 API,可与制造商的图形驱动程序实现方法交互。应用开发者可通过三种方式将图像绘制到屏幕上:使用 Canvas、OpenGL ES 或 Vulkan。一、Android 图形组件无论开发者使用什么渲染 API,一切内容都会渲染到“Surface”。Surface 表示缓冲队列中的生产方,而缓冲队列通常会被 SurfaceFlinger 消耗。在 Android 平台上创建的每个窗口都由 Surface 提供支持。所有被渲染的可见 Surfac

2020-06-26 19:04:48 178

原创 Android 源码 installd 启动流程分析
原力计划

installd 进程具有 CAP_DAC_OVERRIDE 特权(Privilege)。对于具有 CAP_DAC_OVERRIDE 特权的进程,Linux 会跳过文件的读、写和执行权限的检查。所以,installd 可以访问任何目录下的文件。system 用户则会受限。而 PackageManagerService 属于系统进程,system 用户并没有访问应用程序目录的权限,这就需要委托给 installd 处理。SystemServer 类 startBootstrapServices() 方法中

2020-06-09 19:41:46 190

原创 Android 源码 PackageManagerService 启动流程分析
原力计划

《Android 源码 installPackage 流程分析》一节着重分析了 apk 安装流程,接下来我们分析 PackageManagerService 启动时都做了些什么?执行 PackageManagerService main 静态方法;调用 PackageManagerService 类 isFirstBoot() 方法;调用 PackageManagerService 类 getUsageStatsIfNoPackageUsageInfo() 方法;调用 PackageManager

2020-06-08 17:45:04 176

原创 Android 源码 installPackage 流程分析
原力计划

installPackage 安装流程最终会调用 PackageManagerService 对应方法,当然是使用 binder 机制得以实现跨进程通信。先来看看 installPackage 流程具体和各种进程如何关联调用,有个整体印象以后我们再来分析其流程。起点是 ApplicationPackageManager 类 installPackage 方法。frameworks/base/core/java/android/app/ApplicationPackageManager.java/*

2020-06-05 21:47:29 962

原创 Android 源码 关机流程分析
原力计划

Power 键长按 3s 可触发设备关机流程,关机我们能想到的有首先结束当前正在运行的界面,接着关闭显示屏,然后各种设备下电,最后设备彻底关闭。在《Android 源码 输入系统之 InputReader》一节中,调用 InputDispatcher 类 notifyKey 方法,其中调用了 InputDispatcherPolicyInterface(mPolicy) 类的 interceptKeyBeforeQueueing 方法,这会拦截关机键输入事件。frameworks/native/ser

2020-06-02 22:05:21 141

原创 Android 源码 输入系统之事件窗口分发
原力计划

handleReceiveCallback 方法对消息进行处理。上一节打通了 InputDispatcher 和输入窗口之间双向的通道,这是通过 InputChannel 承载的。现在可以继续分析从 InputDispatcher 发送出的事件如何被接收处理了。NativeInputEventReceiver 类 handleEvent 被调用,用来处理 InputDispatcher 发送来的事件。frameworks/base/core/jni/android_view_InputEventRec

2020-06-02 21:36:34 141

原创 Android 源码 输入系统之 InputChannel 通信通道建立
原力计划

上一节完成了焦点窗口关联,现在可以分析如何将输入事件继续从 InputDispatcher 继续分发。InputChannel 的 sendMessage 将消息发送出去。实际是调用 socket 的 send 接口来发送消息的。具体一点其实使用的是 socketpair。所以我们先来学习 Linux 如何使用 socketpair,然后“破解” InputChannel 通信,最后再去分析输入事件窗口分发。一、socketpair 使用用于创建一对无名的、相互连接的套接字。#include <

2020-06-01 21:22:35 156

原创 Android 源码 输入系统之窗口关联
原力计划

在前一节中,InputDispatcher 的事件派发工作调用 InputChannel sendMessage 方法标志着 InputDispatcher 一个周期的工作结束。但意味着事件找到对应的窗口处理的开始。上一节中 mFocusedWindowHandle 是 InputDispatcher 的成员变量,它是确定发送事件消息的关键。我们以它为突破口寻找“出路”。mFocusedWindowHandle 在 setInputWindows 方法中进行了赋值,我们需要反推一下。frameworks

2020-06-01 21:20:15 147

原创 Android 源码 输入系统之 InputDispatcher
原力计划

InputDispatcherThread 线程负责派发事件。InputDispatcherThread 启动后会执行 threadLoop 函数。threadLoop 函数返回 true,InputDispatcherThread 就会循环执行 threadLoop 函数。具体可以参见关于 Native Thread 实现一节《Android 源码 Native Thread 分析》。InputDispatcherThread(称为“ InputDispatcher”)线程在队列上等待新事件,并异步将其分

2020-06-01 21:18:23 132

原创 Android 源码 输入系统之 InputReader
原力计划

InputReaderThread 线程负责读取事件。InputReaderThread 启动后会执行 threadLoop 函数。threadLoop 函数返回 true,InputReaderThread 就会循环执行 threadLoop 函数。具体可以参见关于 Native Thread 实现一节《Android 源码 Native Thread 分析》。InputReaderThread(称为“ InputReader”)读取并预处理原始输入事件,应用策略,并将消息发布到由 InputDispat

2020-05-31 15:18:34 176

ORMLite和GreenDao性能对比Demo

ORMLite和GreenDao性能对比Demo,两个常用数据库ORM框架用法与比较

2016-01-03

android使用html写一个关于页面

使用html写一个android的关于页面,动态修改版本号,让你从繁重的Textview 堆砌中彻底解放出来

2015-11-07

Android FTP客户端与服务端

两部手机其中一部手机作为服务器,另一部手机作为客户端下载,使用FTP方式传输文件,图片下载,多图加载,滑动停止加载完整DEMO。

2015-09-13

MPAndroidChart

关于MPAndroidChart就不多说了,是一个开源的android图表库,包含折线图、柱状图、散点图、雷达图等等,功能非常强大

2015-09-05

Android图片局部放大镜

图片上某一点看不清楚,你不需要将整张图片都放大,只需要放大你想看到的部分,这个时候放大镜就派上用场了。

2015-08-16

Android发送邮件功能实现

使用commons-net-3.3.jar或mail.jar核心邮件包实现邮件发送功能,可发送附件、图片、HTML邮件,灵活控制,甚至实现后台发送邮件功能!

2015-08-16

android图片堆叠效果实现

android图片堆叠效果实现,实现任意小角度堆叠显示,可用于图片相册缩略图

2015-07-18

软件内每日提醒功能实现

软件内每日提醒功能实现,可添加到工程中实现每日提醒,隔天提醒等提醒功能

2015-07-12

可分割的环形进度条

可分割的环形进度条,适合倒计时等场景,已经定义好,只需把文件拷入即可使用

2015-06-13

高仿今日头条字体渐变指示器

今日头条的指示器很炫酷,随着你的滑动字体颜色可以逐渐的变化,实现方法主要是使用自定义控件结合ViewPager。 CompleteTrackColorViewDemo实现高仿今日头条字体渐变指示器,滑动+点击切换,如丝顺滑

2015-04-26

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除