自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

夏的专栏

士不可不弘毅,任重而道远

  • 博客(151)
  • 资源 (2)
  • 收藏
  • 关注

原创 Kotiln基础语法总结(三)

一、扩展属性除了给类添加扩展函数外,你还可以给类定义扩展属性,给String类添加一个扩展,这个扩展属性可以统计字符串里有多少个元音字母。val String.numVowels get() = count { "aeiou".contains(it) }fun <T> T.easyPrint(): T{ println(this) return this}fun main() { "if this char sequence conta

2022-05-26 20:37:32 426

原创 Kotiln基础语法总结(二)

一、主构造函数我们在Player类的定义头中定义一个主构造函数,使用临时变量为Player的各个属性提供初始值,在Kotlin中,为便于识别,临时变量(包括仅引用一次的参数),通常都会以下划线开头的名字命名。class Player( _name: String, _age: Int, _isNormal: Boolean){ var name = _name get() = field.capitalize()

2022-05-22 16:08:22 313

原创 Kotiln基础语法总结

kotlin不仅支持编写在虚拟机上运行,而且还是一门跨平台的通用型语言,我们可以用Kotlin开发各种类型的原生应用,如Android,macOS,Windows,Javascript应用。Kotlin能脱离虚拟机层,直接编译成可以在Windows,Linux和macOS平台上运行的原生二进制代码。一、变量变量声明//Int类型可以省略,自动推导var max: Int = 5//var 可读可写//val 可读不可写常用内置数据类型类型描述示例String字符

2022-05-20 08:13:17 546

原创 ViewPager和WebView滑动冲突问题

最近项目开发中,许多地方用到了WebView,这样会出现一个问题就是WebView滑动和ViewPager滑动冲突,网上找了很多方案,终于借鉴这篇文章的思路解决了问题处理 WebView 与 ViewPager 滑动冲突具体原理都是参考的文章解决的。代码段只需要重写WebView下面方法就可以完成了,不需要与js交互。//最大递归深度int MAX_PARENT_DEPTH = 3;//在WebView的onTouchEvent事件为ACTION_DOWN时,查找父视图是否是可以滑动的视图(

2021-11-21 20:57:20 2807

原创 音视频系列--OpenSL ES基础用法总结

一、前置OpenSL ES全称为Open Sound Library for Embedded Systems,及嵌入式音频加速标准。OpenSL ES是无授权费、跨平台、针对嵌入式系统封精心优化的硬件音频加速API。它为嵌入式移动多媒体设备上的本地应用程序开发提供了标准化、高性能、低响应时间的音频功能实现方法,同时还实现了软/硬件音频性能的直接跨平台部署,降低了执行难度。在Android中,High Level Audio Libs是音频Java层API输入输出,属于高级API,相对来说,OpenS

2021-05-02 13:18:24 1479 1

原创 音视频系列--CLion搭建SDL和FFmpeg环境(Window)

一、环境搭建1.1、软件下载最近用CLion搭建了FFmpeg和SDL的环境,方便学习下CLion链接包含破解文件链接:https://pan.baidu.com/s/18ZkHu9urnbSL-ssgWbjTjQ提取码:1tun复制这段内容后打开百度网盘手机App,操作更方便哦编译器用的MinGW,配置如下SDL下载地址FFmpeg下载地址注意, FFmpeg和SDL目录中bin,include,lib中文件都要拷贝到MinGW的对应目录中,不然编译会找不到1.2、CM

2021-04-16 19:28:15 903

原创 音视频系列--OpenGL美颜特效

美颜分两种高斯模糊美颜需要手动保留细节部分,不适合,但是高斯模糊美颜效果比较好通道磨皮美颜1.蓝通道 更容易保存视频的细节信息2.高反差保留3.叠加4.调rgb曲线 二次曲线美颜的本质去痘一般是高斯模糊美颜之后,再进行通道美颜precision mediump float;//顶点着色器传递过来的坐标varying mediump vec2 aCoord;//采样uniform sampler2D vTexture;vec2 blurCoordinates[20];/

2021-03-10 22:40:47 1291

原创 音视频系列--OpenGL+FBO录制视频

上一篇讲了用OpenGL纹理渲染摄像头数据,这一篇打算利用上一篇的开发成果,录制视频。一、FBO前面讲的利用OpenGL纹理渲染的Camera数据是直接显示到屏幕的,但是在直播推流时候是不能这么做的,这时候得把用OpenGL渲染出来的数据放到一个容器中,然后用这个容器的数据去显示到屏幕,或者录制,或者去直播推流就行了。这个容器就是这里要介绍的FBO(Frame Buffer object),离屏缓存。我们需要对纹理进行多次渲染采样时,而这些渲染采样是不需要展示给用户看的,所以我们就可以用一个单独的缓

2021-03-06 15:17:47 1012

原创 音视频系列--OpenGL纹理+CameraX滤镜渲染

上一篇写了OpenGL基础理论最近趁着空余时间把OpenGL纹理学习了,然后结合CameraX做了下滤镜效果,还是打算记录下学习效果。关于纹理的介绍可以学习这篇文章一、CameraRender数据源使用CameraX,没有Camera2代码的复杂,CameraX的使用比较简单,之前写的这篇文章有过CameraX的介绍使用,这里不做过多赘述了。public class CameraRender implements GLSurfaceView.Renderer, Preview.OnPreview

2021-03-06 11:00:08 1293 3

原创 音视频系列--OpenGL基础理论概念

一、OpenGLOpenGL是一种图形应用程序编程接口(Application Programming Interface,API)。它是一种可以对图形硬件设备特性进行访问的软件库,OpenGL被设计为一个现代化的、硬件无关的接口,因此我们可以在不考虑计算机操作系统或窗口系统的前提下,在多种不同的图形硬件系统上,完全通过软件的方式实现OpenGL的接口。二、OpenGL EShttps://www.khronos.org/opengles/OpenGL® ES is a royalty

2021-02-06 17:23:05 579

原创 音视频系列--rtmp直播推流学习(软编)

x264编译#!/bin/bashNDK=/home/ruby/Desktop/android-ndk-r21dexport TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64export API=21function build{ ./configure \ --prefix=$PREFIX \ --disable-cli \ --enable-static \ --enable-pic \

2021-01-28 22:45:58 959

原创 音视频系列--rtmp直播推流学习(硬编)

上一篇介绍了怎么搭建流媒体服务器,这一篇打算利用这个流媒体服务器,实现rtmp音视频的推流服务。实现效果如下,右边是模拟器推流端,左边是利用vlc来测试推流情况。直播源是使用MediaProjection来实现,之前有学习怎么用它投屏。rtmp介绍下载地址rtmp导入#子文件cmakelist#关闭ssl 不支持rtmps rtmp 加密 传递一变量 进制 加密验证set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO" )file(GL

2021-01-20 13:41:54 1096 1

原创 音视频系列--Camera2+MediaCodec制作相互投屏效果

接着之前写的 音视频系列–MediaProjection+MediaCodec制作简单投屏效果,继续使用Camera2+MediaCodec来制作相互实时投屏效果,为后面的直播学习打下基础。一、效果模拟器作为客户端,手机作为服务端,用模拟器实时接收的手机投屏数据,如果是两个手机可以相互投屏。整个过程使用Camera2来获取数据,获取的数据通过MediaCodec编码,使用H264协议,传输通过WebSocket来实现,接收端接收到数据之后解码,然后通过TextureView渲染,大概是这么一个流程

2021-01-10 13:07:25 1204 5

原创 音视频系列--音频基本操作(音频裁剪,音频和音频混合,音频和视频混合)

前面介绍了音频的基本原理,这篇文章继续来总结下音频的基本操作,包括裁剪,混音和音频和视频的混合操作。一、裁剪下面Demo将一段输入mp3文件,根据startTime和endTime,进行裁剪,先解码成PCM文件,然后转码成WAV//解码成PCM文件public void decodeToPCM(String musicPath, String outPath, int startTime, int endTime) throws Exception { if (endTime < s

2021-01-10 10:03:43 1296

原创 音视频系列--音频基本理论

一、何为声音中学物理中我们知道,声音是物体振动产生的声波。声音通过介质(空气、固体、液体)传入到人耳中,带动听小骨振动,经过一系列的神经信号传递后,被人所感知。声音是一种波。物体振动时会使介质(如空气)产生疏密变化,从而形成疏密相见的纵波。既然声音是波,那么我们就可以用图的形式来表示它。给定空间中某一点,该点的空气疏密随时间的变化如下:波形图下图是一个正弦波,其周期为0.002s,频率为500HZ。频率(音调):声音1秒内周期性变化的次数人耳的听觉范围在20Hz-20kHz。 低频的声音

2021-01-05 22:04:40 1475

原创 音视频系列--MediaProjection+MediaCodec制作简单投屏效果

最近学习了使用MediaProjection+MediaCodec来制作简单的投屏效果,感觉作为练手Demo还是算合适的,趁此记录下学习效果。一、效果大概流程如下效果和手机投屏到电脑上差不多,整个过程使用MediaProjection来录制屏幕,录制好的数据通过MediaCodec获取编码好的数据,使用H265协议,传输通过WebSocket来实现,大概是这么一个流程,下面记录下实现过程。二、MediaProjection屏幕录制首先还是获取MediaProjectionManager,然后

2020-12-22 22:49:24 2741 1

原创 音视频系列--MediaProjection录屏生成H264和H265文件

一、前言想要分析H264或者H265文件,就需要生成对应文件来分析,当然可以通过FFmpeg来操作,操作命令可以参考这里,这里打算使用MediaProjection录频来生成下H264或H265文件。二、MediaProjection2.1、获取MediaProjectionManager使用之前别忘了申请权限 public boolean checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.

2020-12-21 15:29:23 1201

原创 音视频系列--哥伦布编码和H264片段sps解析宽高信息

H.264码流中的NALU进行了一个简单的划分,标出了NALU的类型和长度等信息。因为我们在解析SPS和PPS中要使用到指数哥伦布编码的解析,所以有必要了解一下指数哥伦布编码。一、指数哥伦布编码(理论篇)指数哥伦布码(Exponential-Golomb code, 即Exp-Golomb code)是熵编码的一种编码方式,正常来说,可以拓展为k阶,但是在H264中使用的是0阶指数哥伦布编码,在H.264中使用ue(v)表示0阶无符号指数哥伦布编码的解码过程,用se(v)表示0阶有符号指数哥伦布编码过

2020-12-20 22:22:33 999

翻译 音视频系列--H264编解码总结

一、概述H264,通常也被称之为H264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)对摄像头采集的每一帧视频需要进行编码,由于视频中存在空间和时间的冗余,需要用算法来去除这些冗余。H264是专门去除这些冗余的算法,我们把这种算法称为H264编码。H264的出现就是为了创建比以前的视频压缩标准更高效的压缩标准,使用更好高效的视频压缩算法来压缩视频的占用空间,提高存储和传输的效率,在获得有效的压缩效果的同时,使得压缩过程引起的失真最小。MPEG-4 AVC和H.26

2020-12-20 19:26:05 6731

翻译 音视频系列--cmake学习

之前写过一篇cmake的简单使用,这次准备详细总结下cmake的相关使用。一、什么是库库是写好的,成熟的,可以复用的代码,一般程序运行都需要依赖许多底层库文件。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行,库有两种:静态库(.a、.lib)和动态库(.so,.dll)。静态、动态是指链接,将一个程序编译成可执行程序步骤如下:c或cpp文件程序编译过程一步到位编译:gcc main.c -o main预处理 -E (.i) 编译 -S (.s) 汇编-c (.o)

2020-12-05 19:46:42 611

原创 音视频系列--c++语言学习(常函数,友元函数,继承,多继承,虚函数和纯虚函数)

一、常函数既要使数据能在一定范围内共享,又要保证它不被任意修改,可使用const。1 .用const修饰的声明数据成员称为常数据成员2 .用const修饰的声明成员函数称为常成员函数3 .用const修饰的定义对象称为常对象变量或对象被const修饰后其值不能被更新。因此被const修饰的变量或对象必须要进行初始化。1.1、常数据成员有两种声明形式:const int cctwl;int const cctwl;//不能省略数据类型,可以添加 public private等访问控制

2020-11-27 21:23:23 350

原创 音视频系列--c++语言学习(构造函数、拷贝构造函数、explicit、new、内存分布)

一、构造函数1.1、构造函数和析构函数由来类的数据成员不能在类的声明时候初始化使用构造函数处理对对象的初始化。1 .构造函数是一种特殊的成员函数,与其他函数不同,不需要用户调用它,而是创建对象的时候自动调用。2 .析构函数是对象不再使用的时候,需要清理资源的时候调用。1.2、构造函数和析构函数基本语法1.2.1、构造函数1.C++中的类需要定义与类名相同的特殊成员函数时,这种与类名相同的成员函数叫做构造函数;2.构造函数可以在定义的时候有参数;3.构造函数没有任何返回类型。4.构

2020-11-22 23:27:40 192

原创 音视频系列--c++语言学习(内联函数,默认参数,函数重载,函数指针,宏定义防止多次导入,this)

一、内联函数c++从c中继承的一个重要特征就是效率。假如c++的效率明显低于c的效率,那么就会有很大的一批程序员不去使用c++了。在c中我们经常把一些短并且执行频繁的计算写成宏,而不是函数,这样做的理由是为了执行效率,宏可以避免函数调用的开销,这些都有预处理来完成。但是在c++出现之后,使用预处理宏会出现两个问题:1 c中也会出现,宏看起来像一个函数调用,但是会有隐藏一些难以发现的错误。和实际的函数调用不一致2 面向对象是c++特有的,预处理器不允许访问类的成员,也就是说预处理器宏不能用作类

2020-11-22 18:08:32 186

原创 音视频系列--c++语言学习(类和对象,命名空间,cin和cout,引用)

从语法上看,C语言是C++ 的一部分,C语言代码几乎不用修改就能够以C++ 的方式编译。学了C语言就相当于学了C++的一半,从C语言转向C++时,不需要再从头开始,接着C语言往下学就可以。一、类和对象C++ 是一门面向对象的编程语言,理解 C++,首先要理解类(Class)和对象(Object)这两个概念。C++ 中的类(Class)可以看做C语言中结构体(Struct)的升级版。结构体是一种构造类型,可以包含若干成员变量,每个成员变量的类型可以不同;可以通过结构体来定义结构体变量,每个变量拥有相同的

2020-11-22 13:04:21 752 1

原创 音视频系列--c语言学习(二级指针,函数指针,复杂指针函数,字符串,常量指针,文件操作)

一、指针间传值详解1.1、值传递行参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参 -> 形参),参数的值只能传入,不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。1.2、指针传递形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行操作。1.3、引用传递形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是

2020-11-15 16:46:06 294

原创 音视频系列--c语言学习(结构体,指针,位运算,内存管理,异常指针)

C语言是学习音视频开发必须要掌握的,当然也没有必要学得多么深,只需要掌握常用的一些用法就可以了,这里记录下常用的语法。一、结构体1.1、结构体类型的定义struct Person{ char name[64]; int age;};typedef struct { char name[64]; int age;}Person;注意:定义结构体类型时不要直接给成员赋值,结构体只是一个类型,编译器还没有为其分配空间,只有根据其类型定义变量时,才分配空间,有空间后

2020-11-09 00:02:32 682

原创 Framework系列-Binder通信流程(一)

Binder是Android进程通信过程的机制,也是非常复杂的,整个通信过程涉及到用户态和内核态,从java层到Framework层,到驱动层,以前断断续续的看了不少文章,总是不能看到本质,所以不能表达出原理思想。最近看了几篇文章,写得挺好的,所以趁此将整个过程记录下来,方便后续复习。当然也有理解不到位的,不过大致方向应该没错,想了解更多的可以看后面的链接文章。分析的源码8.0涉及源码\frameworks\base\core\java\android\content\ContextWrapper.ja

2020-11-01 18:09:39 478

原创 Framework系列-Binder通信流程(二)

涉及源码\frameworks\base\core\java\android\content\ContextWrapper.java\frameworks\base\core\java\android\app\ContextImpl.java\frameworks\base\core\java\android\app\ActivityManager.java\frameworks\base\core\java\android\os\ServiceManagerNative.java\framewo

2020-11-01 17:29:38 244

原创 Linux中mmap函数使用

一、前言除了标准的文件IO,例如open,read,write,内核还提供接口运行应用将文件map到内存,使得内存中的一个字节与文件中的一个字节一一对应。这就是今天要说的mmap,它在android中的用处非常多,比如binder,还有腾讯的开源的IO框架MMKV。这里简单记录下使用。二、优势和缺势优势1 .读写文件避免了 read() 和 write() 系统调用,也避免了数据的拷贝。2 .多个进程 map 同一个对象,可以共享数据。3 .可以直接使用指针来跳转到文件某个位置,不必使用

2020-09-20 16:44:00 797

原创 虚拟机相关知识--面试专用

class文件能够被JVM识别,加载并执行的文件格式,记录了一个类文件的所有信息。生成一个class文件,可以通过两种方式:通过IDE自动帮我们build手动通过javac去生成class文件class文件格式详解:一种8位字节的二进制流文件各个数据顺序紧密的排序,无间隙每个类或接口都单独占据一个class文件javap -verbose TestClass查看字节码内容Java class文件结构(规范篇)Java class文件结构(实例篇)class文件弊端:内存

2020-08-25 12:46:28 283

转载 深入学习性能优化--面试使用

转载地址1、 你对 APP 的启动有过研究吗? 有做过相关的启动优化吗?程序员:之前做热修复的时候研究过 Application 的启动原理。项目中也做过一些启动优化。面试官:哦,你之前研究过热修复? (这个时候有可能就会深入的问问热修复的原理,这里咱们就不讨论热修复原理) 那你说说对启动方面都做了哪些优化?程序员:1 .我发现程序在冷启动的时候,会有 1s 左右的白屏闪现,低版本是黑屏的现象,在这期间我通过翻阅系统主题源码,发现了系统 AppTheme 设置了一个 windowBackg

2020-08-23 16:15:58 388

原创 并发系列--Future和Callable

一、Runnable的缺陷在多线程开发中,一般都会使用Runnable来处理异步任务,但是它有一定的缺陷1、不能返回一个返回值2、也不能抛出checked Exception接着就可以引入下面主题,Callable和Future,它在Android源码中很多地方使用到了,比如AsyncTask中,学会了Callable和Future,就可以更方便看源码。二、有返回值Callable接口它是一个接口,约定了线程要做的事情,作用:1、类似于Runnable,被其它线程执行的任务2、实现cal

2020-08-21 23:34:06 853

转载 深入学习java各种容器--面试使用

转载地址对着原文走了一遍流程,分析地址是androd sdk中的29中的源代码分析,和原文地址jdk源码分析有点区别,大体一致前言相信大家在工作中使用容器的场景是具有多变性的,那么在性能方面你知道怎么去选择一种当前最优的数据结构吗? 或许对于工作多年有经验的开发者来说,是没有问题的。但是对于刚入门 1 ~ 2 年或者只知道怎么使用而不知道对当前最适用的,那么这一篇文章将全面为你解惑。该篇还是延续上一篇 面试官: 说一下你做过哪些性能优化? 的风格,以问答的模式来进行解答,相信对你是有帮助的。如

2020-08-15 19:41:55 284

原创 并发系列--CAS原理

概述在平时多线程开发中,一般为了保持代码的同步性,不使代码在多线程环境下出错,都会给代码加synchronized锁,这样固然会使问题得到解决。但是每次在调用对应方法时候,都会获取或者等待锁释放,会有一定的性能问题,因为线程从阻塞到运行,都会有对应的状态切换,可能线程状态切换的时间比同步代码块的执行时间还长,这样性能会受到一定程度的影响。这时候就可以引入本章要介绍的话题,CASCAS是什么CAS是英文单词CompareAndSwap的缩写,中文的意思是:比较并替换。底层通过利用 CPU 的 CAS 指

2020-08-15 10:05:20 364

原创 并发系列--Java中的各种锁

Java中的各种锁Lock接口Lock简介,地位,作用锁是一种工具,用于控制对共享资源的访问Lock和Synchronized,这两个是最常见的锁,它们都可以达到线程安全的目的,但是在使用上和功能上又有较大的不同Lock并不是用来代替synchronized的,而是当使用synchronized不合适或不满足要求的时候,来提供高级功能的。Lock接口最常见的实现类是ReentraintLock通常情况下,Lock只允许一个线程来访问这个共享资源。不过有的时候,一些特殊的实现也可允许并发访问,比

2020-08-14 22:37:50 291

原创 并发系列--Synchronized使用与原理

前言Synchronized在多线程中使用得比较多的,这两天看了下慕课网相关课程,在此总结下其使用和原理作用:Synchronized据有可重入,不可中断性,能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果,内部是通过monitor来加锁和解锁的。地位:1.Synchronized是java的关键字,被java语言原生支持。2.是最基本的互斥同步手段。3.是并发编程中的元老级角色,是并发编程的必学内容。不使用并发的后果两个线程同时a++,如果不加锁,最后结果

2020-08-09 12:16:15 208

原创 并发系列--ThreadLocal

前言阅读ThreadLocal以前在看源码的时候会使用到,并且面试时候也会问到,最近趁空余时间看了下源码,来此总结下。ThreadLocal是线程内部的数据类,通过它可以在指定的线程中存储数据,对于其它线程是无法获取到数据。借此可以实现一些特殊功能。使用场景一、场景一 每个线程需要一个独享的对象当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal。最常见的使用场景就是Handler的Looper,它的作用域就是线程并且不同线程具有不同的Looper,

2020-08-08 14:36:16 317

原创 Breakpad使用(window)

Chromium的Breakpad是目前Native崩溃捕获中最成熟的方案,这里参考下Android高手课中的Demo,来学习下怎么使用1.Chapter01例子里集成了Breakpad 来获取发生 native crash 时候的系统信息和线程堆栈信息。通过一个简单的 Native 崩溃捕获过程,完成 minidump 文件的生成和解析,在实践中加深对 Breakpad 工作机制的认识。只是Demo里面提供的minidump_stackwalk可能由于环境不同,无法启动,所以需要单独编译。在网

2020-05-30 11:59:14 1252

原创 FFmpeg4.2.2 交叉编译

这两天一直在编译FFmpeg库,实话真是踩坑不少,也知道了遇见问题该如何排错,所以还是打算记录下,也算是一个总结.百度了解FFmpeg环境和下载1 .CentOs 82. android-ndk-r17c3. ffmpeg-4.2.2注意要下载linux版的ndk,在获取下载链接时候,通过wget下载到linux中Configure帮助选项查看帮助选项 ./configur...

2020-01-21 17:37:20 2861 1

原创 音视频系列--Shell脚本编程入门

说句题外话,19年互联网整体环境不太好,裁员挺严重的,现在真的能有一个稳定的工作已经算是可以了,前些年的互联网热潮已经过去了,再也不是那种会四大组件就可以随便进入一家公司的年代了,现在找工作不仅要会使用某个东西,而要知道里面的实现原理,需要有一个比较强的技术实力,才能找到一份符合自己愿望的公司。所以程序员就是要时刻保持一个学习的心态,对于除了自己工作中用到东西,更需要对工作之外的东西学习,学到老,...

2020-01-18 14:40:10 519

react版的TodoList

todoList学习使用,

2019-03-31

ContentProvider使用

ContentProvider学习使用

2016-12-04

空空如也

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

TA关注的人

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