学了一点Android,想写点东西。今天和大家分享下啊!
摘要
本系统主要对基于Android平台的天气预报软件的实现进行研究。软件系统的主体功能是利用网络访问和风天气提供的端口获取实时天气、预测天气状况及各种环境参数。并以图文并茂的形式通过软件展示给用户。可以通过软件设置城市获得所需的城市的天气状况。软件主要体现在用户体验上,工具箱中有多种应用。如拍照、查看相册及手电筒等。对用户设置的城市进行管理,方便用户再次查询。加强软件的可行性。
1.作品简介
随着移动互联网的兴起及Android机的普及,智能手机已经成为人们日常生活中必比可少的工具。尤其国产Android手机的发展快速迅猛,相比于苹果手机有价格上的优势,故市场潜力巨大。目前,手机的功能已经不仅仅是打电话发短信,更多的是为我们的生活生产提供便利条件。以往人们不太方便获取的信息,通过手机上网可以实时获取。比如以往人们获取天气预报的方式多为收看电视节目或收听广播,而智能手机的出现可以通过网络更快更方便地获取天气信息。基于以上原因,本项目制作了一款界面简洁,操作简单的Android端天气预报应用。
看天气是一款集成天气预测、实时更新、拍照、手电筒等一体的简单实时小工具。天气数据来源于和风天气,调用系统相机、相册、手电筒等功能。
图1 目录框架
看天气1.0版本实现了根据位置查看中国3240个市县区的实时显示天气状况,7天预测、168小时逐小时预报,以及生活指数实况和预报、空气质量实况和预报,下拉刷新天气状况;我管理的城市可以同时查看3个地区的天气状况;相机以及相册的调用;手机闪光灯的使用(不同的手机和android版本可能用不了),目前只兼容少量机型;分享功能还不完善,目前只能发一段简单的语句;关于是一个简单的本软件介绍。
2.设计思路
2.1UI设计
如上图,采用左滑菜单布局。在界面中大量使用了RelativeLayout、LinearLayout等布局方式。主界面显示一些实时显示天气状况,7天预测、168小时逐小时预报,以及生活指数实况和预报、空气质量实况和预报。测滑菜单设置了一些小工具,方便用户使用,同时一个软件集合了多个软件的功能。体现了我们软件的精髓短小精干。
2.2模块设计
为了完成这个完整的APP,我划分了几个小的模块来实现。首先是天气预报的实现,在天气预报方面我们调用了和风天气的API(https://dev.heweather.com/)来获取实现时显示天气状况,7天预测、168小时逐小时预报,以及生活指数实况和预报、空气质量实况和预报的数据。在把这几个功能分成小个的activity,最后组合为我们看到的主界面。
相机的调用目前只是通过下列代码简单的实现系统相机的调用,没有对相机做任何优化处理。这是需要完善的一个部分,到后面希望可以实现及实时照片的显示,图片原图的优化,防止照片多大而造成内存溢出的严重问题。
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
相册的查看也是一个简单的调用,没有对图片进行处理,排版、图片文件都没有达到选择的目的。这也是需要完善的地方。下面是调用相册的代码。
Intent intent = new Intent(“android.intent.action.GET_CONTENT”);
intent.setType(“image/*”);
startActivityForResult(intent, REQUEST_SYSTEM_PIC);
手电筒目前只能适应部分机型。
3.功能说明
3.1天气查看
天气的实现我们通过使用和风天气的数据来完成天气的查看。通过选择自己所在城市将城市id传入API接口加上天气类型就可以得到对应的数据,接下来就是对数据的Gson化与适配。
3.2相机
目前相机的使用只是做了简单的调用,没有涉及图片处理与优化。
3.3相册
相册的查看我们选择出图片文件展示出来。
3.5手电筒
我们通过调用手机的功能摄像头闪光灯来实现手电筒功能,部分手机可能不能正常使用(完善中)
3.6分享
分享功能可以实现通过QQ或微信发出信息。
4.关键技术
4.1访问网络
在该天气查询中使用到网络访问的问题。下面介绍一下网络访问的相关事项。
因为我们需要访问网络,所以要添加访问网络的权限。代码如下:
4.2Handler消息机制
在开发中更新我们刷新视图都需要在主线程中更新,子线程是不支持更新视图操作的。所以当我们做一些耗时操作的时候可以不能马上得到反馈刷新UI,比如下载文件或者下载图片这些操作都比较耗时,我们一般会重新创建一个子线程异步处理耗时操作,这样就不会堵塞主线程导致卡顿的情况。异步处理成功后如果这个时候我们需要更新视图操作就不能直接更新了,这个时候Handler就起到了作用。我们可以用Handler Looper MessageQueue这套异步消息处理机制来处理这种情况,线程中发送消息通知,主线程来处理消息刷新视图。
Handler消息机制使用了生产消费者设计模式,简单再来说,生产消费者模式就是类似于生活中寄快递一样,寄东西的人可以视为生产者,而快递员就是消息缓存区、快递员负责全部快递的维护和派发、只要还有快递快递员就是一直送到没有为止,收件人就是消费者负责接收快递员的快件。可以看到整个过程发件人不需要关心收件人的具体情况,只需要把收件人的地址写对就行。而快递员也不需要关心发件人和收件人的信息,快递员只负责收快递按快递地址送到到收件人手里。收件人只需要等待快递的送达就好了。
优点
• 低耦合
为什么不直接让消费者调用生产者的某个方法?如果这样直接调用必然会产生相互依赖的情况也就是耦合,如果以后生产者和消费者某一方变化都有可能会影响到对方,但是如果二者直接不直接依赖而是通过缓冲区来交互,这样耦合性就大大减低了。
• 支持并发
生产者可以放心的产生数据直接扔给消息缓冲区,而不用等待消费者那边是否已经处理完了消息,而导致生产者等待状态(生产者消息堵塞),这样就可以不用依赖消费者的处理速度了,互相独立。
• 自由发挥
这种模式还有一好处就是,如果生产者生产的数据速度过快,而消费者那边处理的比较慢,那么这个时候消息都会存在于缓冲区。这样生产者就能慢慢的消费这些数据了,所以定为自由发挥。
流程图
Handler Looper MessageQueue的职责
流程图
MessageQueue 就是设计模式中的缓冲区,它负责接收生产者发送过来的数据先进先出的队列形式,保存着所有消息。在UI Thread中通过looper 不断从MessageQueue 取出消息在执行任务。
Looper 的主要工作就是维护MessageQueque中的消息队列,它负责从MessageQueue中取出要执行的消息任务,先判断Looper是否为null,不为null就循环状态不断从MessageQueue中取出消息,然后通过dispatchMessage派发出去就行处理。
4.3Gson文件解析
Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。而JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,广泛应用于各种数据的交互中,尤其是服务器与客户端的交互。
我们把和风天气平台请求来的数据进行Gson化,转为方便我们处理的数据,并填到对应的位置。即完成了了数据的Gson化。
4.4Fragment使用
Fragment,俗称碎片,自Android 3.0开始被引进并大量使用。作为Activity界面的一部分,Fragment的存在必须依附于Activity,并且与Activity一样,拥有自己的生命周期,同时处理用户的交互动作。同一个Activity可以有一个或多个Fragment作为界面内容,并且可以动态添加、删除Fragment,灵活控制UI内容,也可以用来解决部分屏幕适配问题。
• onAttach():Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。
• onCreate():Fragment被创建时调用。
• onCreateView():创建Fragment的布局。
• onActivityCreated():当Activity完成onCreate()时调用。
• onStart():当Fragment可见时调用。
• onResume():当Fragment可见且可交互时调用。
• onPause():当Fragment不可交互但可见时调用。
• onStop():当Fragment不可见时调用。
• onDestroyView():当Fragment的UI从视图结构中移除时调用。
• onDestroy():销毁Fragment时调用。
• onDetach():当Fragment和Activity解除关联时调用。
Fragment的优势有一下几点:
• 模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
• 可重用(Reusability):多个Activity可以重用一个Fragment。
• 可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好
4.5Drawerlaout
DrawerLayout官方给我们提供的一个侧滑菜单控件,3.0以后引入,低版本使用它,需要v4兼容包, 使用的时候需要注意的是:
1.主内容视图一定要是DrawerLayout的第一个子视图
2.主内容视图宽度和高度需要match_parent
3.代码中使用的时候,要调用openDrawer方法来打开
4.必须显示指定侧滑视图的android:layout_gravity属性
android:layout_gravity = “start”时,从左向右滑出菜单
android:layout_gravity = “end”时,从右向左滑出菜单
不推荐使用left和right,侧滑视图的宽度以dp为单位,不建议超过320dp(为了总能看到一些主内容视图)
4.6viewPage
ViewPager是Android扩展包v4包中的类,她可以实现左右切换当前的view,实现滑动切换的效果。用相应的适配器Adapter关联上面的页卡(View/Fragment)和ViewPager。
PagerAdapter 数据源:List
FragmentPagerAdapter数据源:List
FragmentStatePagerAdapter数据源:ListView
当页卡是View时:用ViewPagerAdapter
当页卡是Fragment时:用FragmentAdapter
4.7数据回调
Intent不但可以实现页面跳转,与带值跳转还可以实现数据回传。
需要注意的是在同一个activity中可能会用onActivityResult(int requestCode,int resultCode ,Intent data)启动多个不同的activity,这时每个activity返回的数据都会回调到onActivityResult()这个方法。因此用requestCode的值来判断数据来源 ,resultCode判断数据处理是否成功。最后取data中的数据。
4.8BaseAdpter适配器
下图展示了数据源、适配器、ListView等数据展示控件之间的关系。我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的。数据适配器正是建立了数据源与ListView之间的适配关系,将数据源转换为ListView能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性。这也体现了Android的适配器模式的使用。对于ListView、GridView等数据展示控件有多种数据适配器。
BaseAdapter的使用主要是通过继承此类来实现BaseAdapter的四个方法:
public int getCount(): 适配器中数据集的数据个数;
public Object getItem(int position): 获取数据集中与索引对应的数据项;
public long getItemId(int position): 获取指定行对应的ID;
public View getView(int position,View convertView,ViewGroup parent): 获取没一行Item的显示内容。
ListView的显示与缓存机制
ListView、GridView等控件可以展示大量的数据信息。假如下图中的ListView可以展示100条信息,但是屏幕的尺寸是有限的,一屏幕只能显示下图中的7条。当向上滑动ListView的时候,item1被滑出了屏幕区域,那么系统就会将item1回收到Recycler中,即View缓冲池中,而将要显示的item8则会从缓存池中取出布局文件,并重新设置好item8需要显示的数据,并放入需要显示的位置。这就是ListView的缓冲机制,总结起来就是一句话:需要时才显示,显示完就被会收到缓存。ListView,GridView等数据显示控件通过这种缓存机制可以极大的节省系统资源。
5.系统测试
我用小米8se,android9.0运行一切正常!
下载:https://download.csdn.net/download/weixin_43849104/11819742