移动设备交互应用 大作业(三)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 移动设备交互应用 大作业(三)

3. 请详细说明“我的垃圾分类APP”的功能、出现的关键问题及解决方案


(1)主要功能:


①登录预览页:


打开APP之后不会立即进入,而是会展示五秒封面之后再进入APP。


7c44bcceb5794347b0dd10340a4a491b.png

②主页:


ab06d85eb5464c01bd953251ec487bd0.png


③语音输入

可以通过语音完成垃圾名的输入:

440148fbe62a4942979619e0d42a94e0.png


b468de42ff774525a5643a3bfd0579eb.png


④图片识别:

可以通过识别上传的图片来完成垃圾的识别


aa5fc35686344033a9d5b2036aa3c9cb.png


⑤版本更新:

此处我通过代码托管平台进行托管,完成版本的更新。


c82824962d0c40548f36299733117707.png


⑥APP评价:

可以通过设置->评价APP链接APPStore对APP进行打分。

由于本APP未发布,故显示No Data


e135180914ff425689bc51dcd3ef2bb4.png


40be46769f9541adad01fb8a6445c1b2.png


43c3ea107df34b57bb5ec3db89d2df75.png

⑦主页上的几个按键:


895bee371ba8491b93e821f2e2f49296.png


(2)遇到的问题及解决办法:


①**Q:ViewGroup为什么不会调用onDraw


A: 正常情况下,我们重写LinearLayout的onDraw方法,它是不会被调用的下面将分析原因并做解释。**

在完成主页面功能栏的布局中,遇到了问题重写LinearLayout的onDraw方法时不会被调用,从而导致错误。


   <com.test.demo.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/ll_absolute"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:background="#FF000000">  
</com.test.demo.MyLinearLayout>  


大概的代码层次是,MyLinearLayout从LinearLayout派生出来,然后在程序中重载OnDraw。但是,onDraw不会被调用。我们可能会遇到这个问题:如果不给LinearLayout设置一个背景,系统是不会调用onDraw时,也就是说,我们重写的onDraw是不会调用的。当设置一个背景后,onDraw就会被调用。


造成这种现象的原因是继承自LinearLayout,而LinearLayout这是一个容器,ViewGroup本身并没有任何可画的东西,它是一个透明的控件,因些并不会触发onDraw,但是如果给LinearLayout设置一个背景色,其实这个背景色不管你设置成什么颜色,系统会认为LinearLayout上面有东西可画了,因此会调用onDraw方法。


我们可以仔细分析View的源码,它有一个方法View#draw(Canvas)方法,这里面有两个地方调用onDraw,它的条件都是:if (!dirtyOpaque) onDraw(canvas);


也就是说,如果dirtyOpaque是true的话,onDraw就不会调用,而dirtyOpaque的值的计算代码如下:

final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&  
             (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);  


此外,View还提供了一个重要的方法:setWillNotDraw:


  public void setWillNotDraw(boolean willNotDraw) {  
     setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);  
 } 

通过查阅资料,得知如果想重写onDraw,应调用这个方法来清除flag,所以如果想要重写LinearLayout的onDraw,可以在其构造方法中调用setWillNotDraw方法。 在ViewGroup初始他时,它调用了一个私有方法:initViewGroup,其中setFlags(WILL_NOT_DRAW, DRAW_MASK); 相当于调用了setWillNotDraw(true),因此对于ViewGroup,它就认为是透明的了。

如果我们想要重写onDraw,就需要调用setWillNotDraw(false)


综上所述:

i.ViewGroup默认情况下,会被设置成WILL_NOT_DRAW,这是从性能考虑,这样一来,onDraw就不会被调用了。

ii.如果要重写一个ViweGroup的onDraw方法,有两种方法:在构造函数里面,给其设置一个颜色,如#00000000或在构造函数里面,调用setWillNotDraw(false),去掉其WILL_NOT_DRAW flag。


②加载条死循环


我的透明进度条原理是不断重绘一个背景图片,然后使用Matrix旋转图片,原先的代码是死循环,代码如下:


 protected Void doInBackground(Void... params) {  
    while( true ) {  
        try {  
            Thread.sleep(100);  
        } catch(InterruptedException e) {  
            e.printStackTrace();  
        }  
        publishProgress();  
    }  
    return null;  
}  


这样就有一个bug,因为是死循环,当ProgressDialog被dismiss掉之后这个循环并不会销毁,而是一直在循环,这样造成的一个bug就是使用了透明进度条之后侧滑菜单点击就没有反应了,并且,透明进度条在Activity下次启动并不会有旋转的效果,这里修改的办法是将这个while(true)改成判断while( mLoop ) 然后重写ProgressDialog的dismiss()方法:


public void dismiss() {  
     super.dismiss();  
     mProgressView.setLoop(false);  
 } 

③使用Logcat进行debug


Logcat 是一个命令行工具,用于转储系统消息日志,包括设备抛出错误时的堆栈轨迹,以及从应用使用 Log 类写入的消息。


Android 日志记录系统是系统进程 logd 维护的一组结构化环形缓冲区。这组可用的缓冲区是固定的,并由系统定义。最相关的缓冲区为:main(用于存储大多数应用日志)、system(用于存储源自 Android 操作系统的消息)和 crash(用于存储崩溃日志)。每个日志条目都包含一个优先级(VERBOSE、DEBUG、INFO、WARNING、ERROR 或 FATAL)、一个标识日志来源的标记以及实际日志消息。


日志记录系统的主接口是共享库 liblog 及其头文件 <android/log.h>。所有语言特定的日志记录工具最终都会调用函数 __android_log_write。默认情况下,它会调用函数 __android_log_logd_logger,该函数使用套接字将日志条目发送到 logd。从 API 级别 30 开始,可通过调用 __android_set_log_writer 更改日志记录函数。

通过使用Logcat可以比较方便的获得程序的运行情况


例如如下情况:

f3e8dab21e104376906e2d59a23a9816.png

9cb1e47494f2401a8c8fb51c5e89e0aa.png

④ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起冲突的问题


在scrollview里面嵌套了一个listview ,通过设置一个方法设置了listview的高度 现在的情况就是进到这个界面的时候看到的不是最上面 而是中间 ,该问题的解决办法为:

mScrollView.smoothScrollTo(0,20);

如此以上代码还是无效, 在代码里去掉listview的焦点 lv.setFocusable(false)即可。

或与EditText一样,在父元素的属性下面下下面这两行即可,不用代码设置。亲测可用。

android:focusableInTouchMode=“true”

android:focusable=“true”

/**   
  * 重新计算ListView的高度,解决ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起冲突的问题   
  * @param listView   
  */    
 public void setListViewHeight(ListView listView) {      
     // 获取ListView对应的Adapter      
     ListAdapter listAdapter = listView.getAdapter();      
     if (listAdapter == null) {      
         return;      
     }      
     int totalHeight = 0;      
     for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目      
         View listItem = listAdapter.getView(i, null, listView);      
         listItem.measure(0, 0); // 计算子项View 的宽高      
         totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度      
     }      
     ViewGroup.LayoutParams params = listView.getLayoutParams();      
     params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));      
     listView.setLayoutParams(params);      
 }  


⑤Theme.AppCompat.Light报错


在styles.xml中<style name=“AppBaseTheme” parent=“Theme.AppCompat.Light”>提示如下错误,这是版本问题。

error: Error retrieving parent for item: No resource found that matches the given name ‘Theme. AppCompat. Light’.

解决方法:

打开任意一个.java文件,输入android.R.style.这时你会看到一个提示列表,仔细看看,再对比一下,看哪个与原有的最接近就选择哪个。用将下划线替换成"."就可了。

将<style name=“AppBaseTheme” parent=“Theme.AppCompat.Light”>改为<style name=“AppBaseTheme” parent=“android:Theme.Light”>同理,将<style name=“AppBaseTheme” parent=“Theme.AppCompat.Light.DarkActionBar”>改为<style name=“AppBaseTheme” parent=“android:Theme.Holo.Light.DarkActionBar”>。


⑥偶发AndroidStudio进入界面卡死,无法进入

经过上网查阅资料后,发现是如下几个原因,并附上解决办法:

如果是因为内存不足:修改studio64.exe.vmoptions studio.exe.vmoptions 2个文件,将文件内分配内存调大即可。

或者是加载时间过长导致一直处于加载状态,此时只需打开AS安装目录下的bin内的idea.properties文件,并在最后加上disable.android.first.run=true


三、实验总结


本次大作业中,我使用了数据持久化与共享技术,网络技术——API接口,安卓权限申请,广播系统,安卓动态绘图,Intent传值完成Activity交互,Fragment碎片布局,Logcat调试,LinearLayout布局。并自学了如何将代码打包成APK,参考网上资料学习了怎么对APP完成版本更新与调用商店进行评分。通过自学第14章,对工程代码进行分层次分结构存储。通过学习第12章也尝试使用了一些精美的UI动画使得APP更美观。

此外,我也自学了Java的相关知识,如线程,单例等等,这些都是我之前没用过也没尝试过的。本次大作业极大的提高的我的编程能力与实际应用能力。由于疫情在家期间自学了Java,在本课程的每次实验乃至本次大作业中,并没有遇到比较多的问题。

通过一学期对《移动设备交互应用》这门课的学习,我的Java代码技术与自学能力得到了很大提升,我也学会了如何将一些点子转化为代码并进行实现。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
114 0
|
6月前
|
小程序 前端开发 JavaScript
微信小程序结合PWA技术,提供离线访问、后台运行、桌面图标及原生体验,增强应用性能与用户交互。
微信小程序结合PWA技术,提供离线访问、后台运行、桌面图标及原生体验,增强应用性能与用户交互。开发者运用Service Worker等实现资源缓存与实时推送,利用Web App Manifest添加快捷方式至桌面,通过CSS3和JavaScript打造流畅动画与手势操作,需注意兼容性与性能优化,为用户创造更佳体验。
178 0
|
9月前
|
vr&ar
什么是云交互技术?实时渲染是云交互吗?
云交互指的是用户与云服务器上的应用实时互动,强调低延迟以避免卡顿。&quot;云&quot;可指公有云、私有云或混合云。实时云渲染是一种云交互技术,将3D应用或大模型放在服务器端,用户设备发送指令,服务器实时处理并反馈视频流。这种技术降低了对用户硬件的要求,尤其是对于3D应用和大模型,减少了使用门槛,支持多种设备交互,促进了数字孪生技术的普及和便利性提升。
280 0
什么是云交互技术?实时渲染是云交互吗?
|
9月前
|
存储 缓存 数据安全/隐私保护
移动应用中的离线模式是一种重要的功能
【5月更文挑战第16天】移动应用的离线模式通过数据缓存和存储确保无网时仍能使用部分功能。数据同步采用延迟策略,用户更改信息后在网络恢复时同步至服务器。为保障安全,敏感数据加密存储并定期备份。开发者还需关注用户体验、电量性能及错误处理,以实现稳定可靠的离线模式,提升用户体验。
270 0
|
9月前
|
存储 缓存 数据安全/隐私保护
说一说你对移动应用中的离线模式的实现。
【4月更文挑战第2天】移动应用的离线模式允许用户在无网情况下仍能部分使用应用,依赖于数据缓存和本地存储。应用在联网时缓存关键数据,离线时从本地读取。数据同步通过延迟策略在重连时完成,敏感信息加密存储并定期备份。开发者还需关注用户体验、性能优化及错误处理,确保离线模式的无缝衔接和稳定性。
318 1
|
9月前
|
存储 缓存 运维
实时云渲染平台有哪些?那个更好用?
实时云渲染平台有哪些?那个更好用?
|
数据采集 Web App开发 资源调度
一日一技:效率提高十倍,Puppeteer 如何启动交互模式?
一日一技:效率提高十倍,Puppeteer 如何启动交互模式?
271 0
|
自动驾驶 定位技术 UED
解码星地一体农机导航:无网作业,极致
星地一体系列农机导航最强大之处是在全国任何地方都拥有信号,即使是在偏远的戈壁滩也能作业,因为星地一体系列导航采用星地融合技术,彻底解决信号问题,通过卫星播发差分信号的服务,在中国,只要可见卫星,就能获取千寻的厘米级定位服务,彻底解决农机导航依赖网络作业的问题。
|
存储 JSON API
移动设备交互应用 大作业(一)
移动设备交互应用 大作业(一)
220 0
移动设备交互应用 大作业(一)

热门文章

最新文章