最近完成了移动编程课程的学习,加上其它安卓开发项目的经历,感觉收获颇为丰富。故在此总结整理安卓开发中比较常见的一些问题,技巧和指南。
android studio是谷歌基于intellij idea社区版开发的,面向安卓开发的免费集成开发环境。其方便快捷的开发调试和可视化ui编辑可以令安卓开发事半功倍。本项目所使用集成开发环境为android studio 4.1.1,编程语言为java,使用jdk 1.8,使用gradle 4.1.1进行项目工程构建和依赖管理。
android studio新建项目时选择一个activity模板作为默认mainactivity,先选择empty activity作为开始。接着,minimum sdk指的是本项目所支持的最小安卓sdk,点击“help me choo”会出现如下界面帮助选择合适的安卓最小sdk版本:
图1 安卓api版本选择帮助界面
其中cumulative distribution表示如果支持该安卓版本以上设备,则预估能支持安卓设备占所有安卓设备的百分比。可见minimum sdk越小所能支持设备越多,但没有必要一味追求支持更多设备,这需要根据一定的市场调查与经验来决定。本项目选择支持默认的安卓6.0及以上。
安卓开发常见的开发模式有mvc,mvp,mvvm等(详见本站文章 “学习笔记 | android开发常用的几种模式”),其中mvc非常容易上手,结构清晰易懂,为了简化开发,本项目使用mvc模式进行开发。
// top-level build file where you can add configuration options common to all sub-projects/modules.buildscript { repositories { //这里放置项目构建仓库 google() jcenter() } dependencies { //这里放置项目构建所需的依赖,而不是模块(总之平时用的依赖一般都不是放这里)的依赖 classpath "com.android.tools.build:gradle:4.1.1" // note: do not place your 顿号的用法及举例application dependencies here; they belong in the individual module build.gradle files }}allprojects { repositories { //依赖包仓库,也就是依赖包从哪下载,一般使用国内镜像下载快很多 maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}//阿里云的仓库,便于下载依赖包 maven{ url "https://jitpack.io"} google() jcenter() }}task clean(type: delete) { delete rootproject.builddir}
模块级构建配置build.gradle(module: $project_name.app)…dependencies {//这里才是放置要用到的第三方依赖的地方 implementation 'androidx.appcompat:appcompat:1.1.0' implementa三明治图片tion 'com.google.android.material:material:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'androidx.fragment:fragment:1.2.4' testimplementation 'junit:junit:4.+' androidtestimplementation 'androidx.test.ext:junit:1.1.1' androidtestimplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'com.squareup.okhttp3:okhttp:3.10.0'//http通信的依赖库 implementation 'com.github.bumptech.glide:glide:3.7.0'//加载图像的依赖库 implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'com.makeramen:roundedimageview:2.2.1' implementation 'com.google.code.gson:gson:2.8.7'}
正如生物一样,activity和fragment作为安卓交互程序也有“生死”,也就是生命周期。
activity生命周期:
如图为一个activity从被启动到被停止的生命周期:
图2 activity生命周期[2]
oncreate(): ativity被创建的时候,常用于初始化基本布局,使用tcontentview()加载布局文件,进行一些其它基本不耗时间的操作,实在需要就用异步线程,避免页面长时间空白。onstart(): activity被展示的时候,也就是说被创建了不一定要显示出来,但要显示出来了才onstart()。onpau(): activity将要被挂起的时候,页面失去焦点无法交互,此时activity仍可见,比如将转入后台运行。onresume():activity已经从后台唤起并显示出来,将要但还未获得焦点无法操作的时候。onstop(): activity以及失去焦点且要转入后台的时候,此时activity已不可见。onrestart(): activity被挂起后又被唤醒的时候,此时activity还未显示出来。ondestroy(): activity被彻底销毁的时候。fragment生命周期:
fragment生命周期与activity周期较为类似,但其中比较十一出游值得提及的是:
android 4.0以后网络请求不能在主线程中执行已经是老生常谈了,这是为例放置线程阻塞应用无响应。解决方案一般就是启动异步线程进行处理,ui线程和网络请求就分离开了,各干各的。但这之间如何通信呢,或者说网络请求结束,不管成功失败,如何告诉ui线程?这将在3.3.3 handler消息处理中提到。
线程通常还要用到线程辅助类runnable,在runnable的要求强制重写的方法run()中执行网络请求任务。例如:
runnable networkrunnable = new runnable() { @override public void run() { //可以在此处执行网络请求和数据解析操作,拉取联系人消息之类 }};thread thread = new thread(networkrunnable);thread.start();//启动线程
不仅如此,耗时操作通常都是在线程中执行的,例如数据库读写和一些其它文件操作之类,可见,多线程是安卓开发中一个重要的技术。
上节中提到,不同线程间如何通信,handler就是一个易用的方案。如果把各个线程比作各干各活的工人,hand自由落体ler就像是个中间人,负责把各个工人传来的消息进行处理,并有权操作ui线程中的组件,比如更新textview的文字(非ui线程是不能操作的)。“工人”如何给handler发一条消息?实现起来很简单,比如网络请求处理成功以后:
private final int network_process_ok = 1;//定义一个数字代号代表网络处理成功private final int network_process_fail = 0; //代表网络处理失败message msg = handler.obtainmessage();//需要保证此时handler的实例handler已经实例化不为空。msg.what= network_process_ok;msg.ndtotarget();//失败以后也可以传回原因:message msg = handler.obtainmessage();msg.what= network_process_fail;msg.obj=reason;//reason一般是string,但可以是任何objectmsg.ndtotarget();
而handler接收到消息后的处理一般如下:
handler = new handler(){ public void handlemessage(message msg) { switch (msg.what) { ca network_process_ok: textview.ttext("处理成功!"); break; ca network_process_fail: textview.ttext("处理失败!原因:" + msg.obj.tostring()); break; } }; };
activity间使用intent类进行跳转和数据传输,具体如下:
intent intent = new intent(this,targetactivity.class);//this是一个activity对象intent.putextra(“param1”,paramstring1);//通过intent传送额外数据,可以在目标activity中,使用getintent()获取传入的intent对象,利用该intent对象的getstringextra()接受传入的string类型参数,当然也有其它类型的,此处不列举。startactivity(intent);
值得注意的是,intent所能传输的数据容量是有上限的,过多的数据不建议使用intent进行传输。
recyclerview是基于viewholder的回收理念在listview上的一个升级版,功能强大,当然在不需要进行回收的场景就当然不要用了,例如实现多行可选择的标签,如果标签滑出屏幕外被回收了的话,选中状态也会一起丢失,除非用额外的对象进行选中状态记录。
recyclerview的适用场景是有大量用于展示的列表数据的场景,比如微信的公众号页面的推文卡片、微信朋友圈、qq的好友列表、小红书的瀑布流帖子等。
和listview类似,要将数据适配到视图上进行展示需要使用适配器adapter,不同的是recyclerview的baadapter已经将viewholder模式封装好了,而目前recyclerview的适配器有很多优秀的第三方库,例如github上开源的cymchad的适配器助手
barecyclerviewadapterhelper,封装了基本的适配器操作,秩序简短的几行代码就能实现基本的适配操作,也封装了很多功能丰富的类与接口,例如可以实现下拉刷新,上拉加载的接口,可以实现多布局共存的multiitemadapter<t>等等[4],因此在合适的场景下使用是很好的,避免重必有勇夫复造轮子,但为了学习和了解更底层的原理,本项目中还是用最原始的listview和recyclerview的自带适配器。
如上所说,列表视图需要一个中间件:适配器,来将数据适配到布局上,这是一个从结构化的数据到结构化的视图的中间过程,纵观整个项目开发,可以发现有很多地方在使用这样的理念,除了列表视图的适配器以外,装载fragment的viewpager的pageradapter也是同样使用了适配器的概念,使得viewpager可以比较方便的管理多个fragment,降低耦合。同样的,这样的理念也可以运用到有着多种网络请求的场景中,使用工厂模式和适配器理念,将网络请求返回结果适配到实体类对象或ui视图里,这对于降低耦合度和提高多态性是很有帮助的。
本文发布于:2023-04-05 11:14:49,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/745a93c8e011c12313c6075ad7198748.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:android菜鸟教程目录(android 四大组件详解).doc
本文 PDF 下载地址:android菜鸟教程目录(android 四大组件详解).pdf
留言与评论(共有 0 条评论) |