欢迎光临外链购买平台,轻松为你获得外链购买的成功案例,友链相关事宜咨询:18978701720,黄经理

外链购买,专注打造匠心好平台

一个好的外链购买,可以为你轻松解决获客难题

Android快速访问系统中的图片和视频

作者:jcmp      发布时间:2021-05-08      浏览量:98
本文来自实际项目所遇到的需求。如果您想直

本文来自实际项目所遇到的需求。如果您想直接查看源代码(实际的项目是由java编写的,但git上的演示是由Kotlin编写的,毕竟,Android的目标是逐步取代java),可以使用kotlin访问:https://github.com/life2smile/PhotoAlbum.git。记住这只是个演示。

1.需求背景

需要扫描系统中存在的视频和图片,并将其显示在宫廷视图中,同时根据图片所在的文件夹对图片进行分组和区分(演示没有实现,可以自行实现)。

2,目标

(1)实现基本相册预览功能,包括视频和图片。

(2)相册按照创建的顺序排序,也就是说,新创建的相册在前面显示。

(3)视频预览显示播放时间。

最重要的是:

优化扫描速度,优化扫描速度,优化扫描速度。

为什么强调优化扫描速度?我将在本文后面讨论它。

3.实现方案

的难点是同时获取视频和图片。图像的预览可以快速获得,但视频预览相对耗时,因此两者之间存在着自然的时间差。在这里,使用两个线程任务分别扫描图片和视频,最后合并成一个集合进行数据呈现。

所以,首先,必须有一个统一的数据结构。众所周知,Android本身已经存储了相册预览的相关数据,并通过ContentResolver公开了查询接口。事实上,这些数据具有很大的公开性,如创建时间、路径等,因此可以在此抽象出多媒体数据结构,实现统一表示。除了这些公共字段之外,还需要添加特定多媒体类型下的字段,如视频持续时间、相册经度和纬度等,并与MediaData统一。

每个模块的实现在下面逐步讨论。

4。界面构建

的思想非常简单,使用ReccyclerView+GridLayoutManager布局。值得注意的是,我们想要的效果是,每个宫殿都与屏幕分开,大小是一样的。因此,首先要得到屏幕的宽度,根据各宫的列数等分,得出大小是每座宫殿的高度和宽度。当然,这只是一个常见的默认宫廷实现,还有其他高度和宽度的定制要求,可以根据自己的要求定制。

5.图片扫描

首先,显影扫描工具类ImageScanHelper的特定功能将在代码体系结构中描述。

/

//kotlin(不再需要懒散加载、多线程java写入)/当然可以更改为伴随对象以实现与java静态的匹配。对象ImageScanHelper{//start是一个公开的扫描接口,它触发相册预览活动中的方法调用//形状,如:ImageScanHelper.start(this.getApplicationContext(),Handler)。//第一个参数是上下文,第二个参数用于处理程序,目的是在收到扫描数据后通知主线程UI更新。趣味开始(上下文:上下文,处理程序:处理程序){//图片扫描相对耗时,这里有一个单独的扫描线程{Doscan(上下文,处理程序)}.start()}私有的兴趣Doscan(上下文,处理程序:处理程序){//来完成数据查询,查询结果可以通过游标游标获得=context.contentResolver.query()。ParseData(光标)。一个私有的有趣的parseData(游标:游标,处理程序:处理程序){//遍历数据,检查我们需要的数据,并将其添加到ImageList中。Do{ImageList.add(MediaData(id,createTime,.)}while(cursor.moveToNext())//通过处理程序将数据传递给UI主线程,用于接口更新Val msg=MediaType.MEDIA_type_IMAGEhandler.sendMessage(Msg)}
6,视频扫描

,正如前面提到的,这是一个难点,因为获取了视频缩略图。Android中有很多可以获得视频缩略图的方案,例如通过MediaMetadataReileever获取第一帧视频,通过ThumbnailUtils获取第一帧,等等。这些方案完全可以获得视频缩略图,但它们有一个很大的缺点,这是非常耗时的解决方案,用户从预览界面,真正看到视频预览的效果需要很长时间,如果视频数量是可以接受的,相反,它是令人发指的。因此,这些方案实际上是不可取的。

那么有更快的方法来获取视频缩略图吗?当然,也有,即查询系统给我们的视频缩略图信息,大大缩短了采集速度,但该方案仍有不足之处,即很多模型无法获得最新的视频缩略图,甚至有些模型除非重新启动手机才能看到新拍摄的视频缩略图,这显然是用户无法接受的。

那么有什么方法可以获得更好的兼容性和更快的扫描速度的视频缩略图呢?

是的!那就是把这两种选择结合起来。详细信息如下:

(1)查询电话缓存缩略图,如果有,保存地址

(2)用于没有缩略图的视频,手动生成缩略图和缓存。然后返回视频缩略图地址

事实上,对于没有缩略图的视频,毕竟有少量的视频,所以上述方案非常接近于简单扫描系统数据缓存所消耗的时间。

代码结构描述如下:

//函数与图片扫描趣味开始(上下文:上下文,处理程序:处理程序){Thread{Doscan(上下文,处理程序)}.start()//函数相同,与图片扫描专用Doscan相同(上下文:上下文,处理程序:处理程序){//扫描视频数据游标=context.contentResolver.query(.)}/函数与图片扫描私有有趣的部分数据(上下文:上下文、游标:游标处理程序:处理程序)相同){do{try{/here将基于接收到的视频数据触发对视频缩略图的扫描,即触发对视频缩略图的扫描。contentResolver.query(.)//获取视频缩略图路径(可能为空),如果不是,则直接获取它,生成缩略图NailPath=姆NailPath.isNullOrempty()。让{//在这里生成缩略图generateThumbNail(FilePath)}//添加扫描视频及其缩略图数据视频列表。添加(MediaData(id、createTime、Consistence、alamame、filePath、umbNailPath、mimeType、NULL、NULL)}Wow(cursor.moveToNext())//向UI线程发送一条消息,扫描视频的代码逻辑是用扫描视频数据Val msg完成的:Message=Message.get()msg.obj=Listmsg.What=MediaType.MEDIA_type_visual handler.sendMessage(G)>。

7。前面提到的数据合并

图片的扫描速度比视频扫描快得多,因此两者之间存在时间差,但最终数据将被合并和呈现。

这里很容易实现,因为这两者都有一个公共的数据结构MediaData,它在向适配器添加了一种数据类型之后调用NotifyDataSetChanged()。

8。保持排序

的时间也很简单。当我们将数据添加到适配器时,我们只需要对列表进行排序。

对于java,只需通过MediaData实现compareto方法,就可以调用Collection s.Sort进行排序。

对于Kotlin,调用List.Sort{}。

9.图片压缩

,因为Android在运行应用程序时有内存限制(具体参考我的另一个博客),在处理图片加载时,您应该特别注意OOM。通用第三方图片加载库已经处理了图片,因为我们使用本机控件,因此需要处理图片。代码如下:

类ImageResize Util{PATY对象{FY Resize(path:string,w:int,h:int):位图{//根据Val Options=BitmapFactor.Options()Options()Options=true;BitmapFactory.decdeFile(路径,选项)//获取缩放比,主要是当解码失败时,选项测量的宽度和高度为-1要考虑这种情况进行处理选项.inSampleSize=Math.max(1,Math.ceil(Math.max(options.outWidth/w,options.outHighth).toDouble()).toInt()选项.inJustDecodeBds=false返回BitmapFactory.deFile(path,}}

10。过滤

可能产生一些不符合我们在前面扫描图片和视频过程中的需要的脏数据或数据。因此,这里我们必须过滤数据。

我们可以简单地使用筛选模式。首先,我们抽象了一个过滤器接口:

//这里我们使用通用设计来满足各种数据输入接口IFilter

然后您可以实现对不同类型的筛选,例如筛选出与大小不匹配的图片(以下只是一个示例,您可以参考git代码):

类ImageSizeFilter:IFilter>{overoverydoFilter(列表:MutableList

最后,源代码地址。同样,代码是基于kotlin的,如果您想要java版本,可以参考实现它的逻辑,或者使用插件转换。