百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

用Kotlin开发了一个Android应用,我只用了8小时

toyiye 2024-06-21 12:18 12 浏览 0 评论

各位小伙伴早上好,上周老家有急事回去了一段时间,回来后赶着做落下的需求加班了一周,于是偷懒了一周没更新,今天继续为大家推送文章,话说年末将至,你们的放假时间定了么?回老家的车票买好了么?好吧,接下来分享来自xfhy同学的投稿文章,文章介绍了他用Kotlin开发了一款Android App,总共耗时8个钟(是的,8个钟,你没看错),当然除去开发时间,前期还花了很多时间去爬数据。

本项目是开源的,需要代码学习的同学可以访问下方的Github地址:

https://github.com/xfhy/DeepNight-in-kotlin


项目简介

这是一款纯看妹子的app,素材全部来源于正经图库,本app仅做学习交流使用,勿做商用。(请注意,全是正经图片,可别想歪了哦)由于开发时间非常紧急,于是没有用MVP,RxJava2,Retrofit这些都没用。直接用的anko的common库,很方便就可以异步操作和UI线程切换等,为了节约点时间,目前项目中有很多需要优化的地方,比如命名不规范,很多地方没有注释等。

说到这里,直接先来几张效果图镇楼。

效果1效果2

效果3效果4

用到的知识点

整个App开发主要用到了以下的知识点:

kotlin 语言

- 数据类

- 伴生对象

- 单例

- 扩展

- 闭包

- anko

- jsoup 爬取网页数据的库

- Material Design 风格

- Recyclerview 瀑布流

- CardView

- Glide 加载图片

- BaseQuickAdapter 以前自己搞的一个adapter,方便快速开发

- DrawerLayout

- NavigationView

- Toolbar

- 下拉刷新,上拉加载

- fragment懒加载

爬取数据

网站非常规律,看看jsoup用法很容易就搞到手啦,下面是详细方法.

首先,我们打开网站,查看网页源代码,可以看到各个分类的网址,待会儿我们可以根据用户选择的分类去爬对应分类的数据.

然后再来看看,每个分类首页(第一页)其实是有一些图片,我们待会儿需要筛选出这些图片的详情页地址,并且这些图片地址我们可以用来展示到app的分类首页上.其实各分类是不止一页的,它们的规律是从第二页末尾就是index_x.shtml结尾,其中x为当前页索引.http://www.msgao.com/dqfl/om/index_2.shtml

我们使用Jsoup开源库去爬取数据,关于Jsoup,其实使用起来非常简单,而且官方还非常人性化的有中文文档,地址.

首先,我们是通过以下方式连接上url

    //连接
     val document: Document = Jsoup.connect(buildUrl).get()

然后我们筛选那些有图片链接的

//筛选首页全部的链接   暂时是第一页的
val htmls: Elements = document.select("a[href$=.shtml]")
//筛选是可以点击进去详情的url
htmls.forEachReversedByIndex {
    val realUrl = it.getElementsByClass("div-img")
    //不正确的全部移除
    if (realUrl.size == 0) {
        htmls.remove(it)
    }
}

接着是获取图片地址和图片标题

//外层列表的bean集合
val outLists: ArrayList<DivListImgBean> = ArrayList()
htmls.forEach {
    val divListImgBean = DivListImgBean("", "","")
    val linkElements = it.getElementsByClass("link")
    divListImgBean.detailsUrl = linkElements.attr("href")
    //获取图片地址
    val imgSrcs = it.select("img[src\$=.jpg]")
    imgSrcs.forEach {
        val src = it.attr("src")
        val alt = it.attr("alt")
        divListImgBean.src = src
        divListImgBean.text = alt
    }
    //添加bean到集合中
    outLists.add(divListImgBean)
}

加入用户点击了某个图片链接,我们就去抓取图片详情页,所有的图片链接,进行该美女的详情展示.在方法上和上面的方法大同小异.

看代码吧,比我说的更清楚.结合jsoup 开发文档和网页源码一起看哟

import com.xfhy.deeplibrary.common.LogUtil
import com.xfhy.deepnight.bean.DivListImgBean
import org.jetbrains.anko.collections.forEachReversedByIndex
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
/**
 * @author xfhy
 * create at 2018/1/1 12:36
 * description:
 */
object NetUtils {
    /**
     * 获取外部的列表页的list
     * @param url url
     * @param index 索引  从1开始
     * @param response 回调数据
     */
    fun reqOutList(url: String, index: Int, response: ZResponse) {
        doAsync {
            try {
                //组装url
                var buildUrl = "${url}index${if (index == 1) "" else "_$index"}.shtml"
                LogUtil.e("buildUrl = $buildUrl")
                //连接
                val document: Document = Jsoup.connect(buildUrl).get()
                //筛选首页全部的链接   暂时是第一页的
                val htmls: Elements = document.select("a[href$=.shtml]")
                //筛选是可以点击进去详情的url
                htmls.forEachReversedByIndex {
                    val realUrl = it.getElementsByClass("div-img")
                    //不正确的全部移除
                    if (realUrl.size == 0) {
                        htmls.remove(it)
                    }
                }
                //外层列表的bean集合
                val outLists: ArrayList<DivListImgBean> = ArrayList()
                htmls.forEach {
                    val divListImgBean = DivListImgBean("", "","")
                    val linkElements = it.getElementsByClass("link")
                    divListImgBean.detailsUrl = linkElements.attr("href")
                    //获取图片地址
                    val imgSrcs = it.select("img[src\$=.jpg]")
                    imgSrcs.forEach {
                        val src = it.attr("src")
                        val alt = it.attr("alt")
                        divListImgBean.src = src
                        divListImgBean.text = alt
                    }
                    //添加bean到集合中
                    outLists.add(divListImgBean)
                }
                LogUtil.e(outLists.toString())
                uiThread {
                    response.onSuccess(outLists)
                }
            } catch (e: Exception) {
                uiThread {
                    response.onError(e.message)
                }
            }
        }
    }
    /**
     * 详情列表
     */
    fun reqDetails(url: String, response: ZResponse) {
        doAsync {
            try {
                //连接
                val document: Document = Jsoup.connect(url).ignoreContentType(true).get()
                val girlPictureList = document.select("div.div-num")
                val imageList: ArrayList<String> = ArrayList()
                girlPictureList.forEach {
                    if (it.hasAttr("data-src")) {
                        var imgUrl = it.attr("data-src")
                        imgUrl = imgUrl.substring(0, imgUrl.indexOf("?"))
                        imageList.add(imgUrl)
                    }
                }
                LogUtil.e(imageList.toString())
                uiThread {
                    response.onSuccess(imageList)
                }
            } catch (e: Exception) {
                uiThread {
                    response.onError(e.message)
                }
            }
        }
    }
}

构建UI

UI交互上,我是采用的侧滑风格的app,中间的数据全部采用fragment来填充的,fragment只有在显示后才加载数据(懒加载机制),不会浪费过多流量。素材取自阿里矢量图标库.阿里妈妈MUX倾力打造的矢量图标管理、交流平台。设计师将图标上传到Iconfont平台,用户可以自定义下载多种格式的icon,平台也可将图标转换为字体,便于前端工程师自由调整与调用。下载图标完全免费,而且还可以调整颜色和大小,更有SVG下载,简直爽翻天.对于我这种一点儿也不会制作图标的菜鸟级程序员来说,简直就是福利。

总结

其实,将一个没有防爬的网站撸成app还是比较简单的,基本上都是这个套路,大家也可以试试.比如内涵段子等,做成app,然后平时可以自己用,还可以给朋友用,还锻炼了自己所学的知识,何乐而不为呢。

Kotlin开发起来真的很顺手,也很方便,就像平时说话一样,很顺畅.大家要学习Kotlin的话,建议多看看kotlin的官方文档。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码