手机卫士01
Posted 抓根宝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手机卫士01相关的知识,希望对你有一定的参考价值。
开题:手机卫士这样的一个项目可以很好的复习基础所学的知识点,因为它覆盖面广,用来做安卓深入学习是一个很好的选择.
1,开始一个项目
写一个好的代码不仅是看功能是否实现,而且代码具有较高的可读性
1.1 代码组织方式:
①采用业务逻辑模块组织代码,以小米阅读为例:
功能一:阅读器reader com.xiaomi.reader
功能二:分享 share com.xiaomi.share
功能三:便签 note com.xiaomi.note
按功能划分包,即使一部分功能被移除了,另外的功能也不会受太大影响.一般用在OA类型的网站,自动化办公的小应用上,各自模块独立
②根据代码的类型组织包结构,以安全卫士为例:
1,界面相关 com.zzx.mobliesafe.activitys
2,服务相关 com.zzx.mobilesafe.service
3,业务逻辑 com.zzx.mobilesafe.engine(引擎)
4,数据库 com.zzx.mobilesafe.db
5,数据库操作包 com.zzx.mobilesafe.db.dao
6工具类 com.zzx.mobilesafe.utils
7自定义view包 com.zzx.mobilesafe.ui
2,_splash(溅,飞洒,卖弄)界面
①展现产品的Logo,提高产品知名度(也可以用作广告页面,打开APP的广告:知乎)
②初始化应用程序的数据
③链接服务器,查找可更新的版本,自动更新
④用户操作指南,新版本特性提醒
布局文件的命名规则:activity_对应的java文件名即可
2.2,
设置界面为全屏更美观:
android:style/Theme.black.NoTitleBar.FullScreen //黑色全屏没有标题栏的界面
在主界面显示版本号
①获取本地APP的版本号,在清单文件中获取
packageInfo = getPackageManager().getPackageInfo(getPackageName()(获取当前APP的文件包名),flags(0,可选标示));
String code = packageInfo.versionName;//清单文件的版本号
这个 API不仅可以获得本APP的,也可以获取别的APP的,通过这个特性可以告知用户更新哪些APP.所以可以把这个API获取版本号抽取出来做成一个工具类
抽取出来的时候要注意,getPackageManager()和getPackageName()都是context调用的,所以抽取的方法需要传入一个上下文,其实也需要传入一个包名.
如果一个方法没有使用类的成员变量就加静态方便调用.
②在界面上显示版本号,定义一个textView(ID命名要规范,控件名_Activity名_用处)
最后把版本号赋值给TextView;
3,源代码的版本控制
3.1 Android项目中不需要被管理的文件夹:
.settings,bin,gen,.project,这些是需要ignore忽视的
需要添加的:
assets(需要原样封装到apk里面的文件),libs(外部引入的jar 包),res(资源),src(源代码),.classpath,AndroidManifest.xml清单文件 ,ic_launcher-web.png图片
proguard-project.text,project.properties(混淆编译的东西)
4.软件自动更新
4.1原理:拿到服务器版本号,跟本地版本号做比较,如果服务器版本号大于本地版本号,就弹出一个对话框,提示用户是否需要更新.
如果需要更新:下载更新信息,替换安装
如果不需要更新,那么可以选择让用户继续访问,或者直接退出程序
如果本地版本号与服务器版本号一致或更高,就进入主界面
4.2 获取服务器的版本号
在splash界面中,onCreate()方法里,链接网络,获取服务器版本号,因为需要访问网络,所以需要放到子线程中,在这里就定义一个类去实现runable
CheckVersionTask类实现 Runable,重写run()方法.
额外:①在tomact服务器中放置一个json文件,保存版本信息:{“version”:”2.0”}
②访问网络路径不要写死了,定义在values中的config.xml文件中String字符串
继续网络访问
一.创建url对象,通过url获取网络链接,设置请求方式,超时时间.
二,获取返回的状态码,判断是否=200.
获取输入流转换成字符串,通过以前的工具类,或者再通过ByteArrayOutputStream,内存输出流把输入流中的信息保存在内存中,最后通过toString方法转换成字符串.(这里有需要对字符串进行转码的操作)
三,对json字符串进行解析JsonObject(大括号就是json对象,中括号就是json数组)
jsonobject.getString(“键的名称”);
额外:需要添加权限.
5,应用程序的错误提醒
当本地版本号小于服务器版本号的时候就需要提示用户更新版本.
提示用户更新版本是在主线程中更新ui,如果在子线程中更新,需要通过handler发送消息.
①创建Message对象 message mes = Message.obtain();
②区分消息mes.what=XXXX;
hanlder.sendMessage(mes);
③在主线程中判断发送过来的消息,如果符合就创建一个对话框,另外还有一些问题也需要通知用户(看需求来,不要把所有的异常全部删掉,一般互联网公司要求都比较多,不同的错误异常需要不同的提示)
实际开发中,主要是把错误代码提示出来(用户不懂什么是异常,但是用户可以把错误代码提交给程序员或者是客服,根据不同的错误代码来区分不同的代码)
④升级提醒的对话框(这里可以考虑抽取一个方法,让handler显得更简洁)
AlertDialog.Builder buider = new Builder(上下文);
指定标题,文本(这里的文本可以在JSON中添加数据,在获取服务器返回的JSON中,解析出来更新的描述内容),确认和取消按钮.
最后记得builder.show();//显示对话框在页面上.
额外:解析出来的中文字符串乱码,windows系统默认GBK(改他就可以),android默认utf-8.
6为了测试splash界面,创建一个主界面.配置清单文件,创建对应的布局文件,在onCreate()中记得 set指定对应的布局文件(可以直接创建Activity文件,eclipse会自动配置好)
6.1在提醒的对话框中,取消升级按钮的点击事件中,通过显示意图(速度快)开启界面,同时关闭splash界面finsh();把它销毁掉.
6.2 确认按钮,在解析的JSON中添加一个path,把新版本的apk下载路径放进去即可.解析到需要更新的时候,把这个路径获取出来,如果用户点了确认,就打开这个路径下载
额外:使用开源框架进行下载,直接通过输入流获取也行(多线程下载即可).
这里就用xUtils框架,顺便练习一下使用.
①获得解析的apk下载路径
②创建httpUtils http = new httpUtis();对象
http.download(下载路径,存放路径,下载状态回调)
③在回调中三个方法,一个成功,一个失败,另一个onLoding()显示下载的进度,显示一个进度条对话框(ProgressDialog),setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)//设置水平方向的进度条,在onLoading中设置最大值和进度数值.最后记得pd.show()
不管是下载成功还是下载失败都记得要dismiss();关闭对话框.
④放到存储卡中记得判断 SD卡的状态:Environment.getExtrnalStorangeDirectory()
如果SD卡不存在就直接进行主界面,并关闭页面,关闭之前提示SD卡不存在
额外:最后还要添加权限,在服务器配置资源文件
项目生成的apk 在bin目录下
7,替换安装应用程序:模板代码
①定义一个意图对象intent = new intent()//需要激活系统的包安装器packageInstaller.
②在上层服务的源码中可以找到它.通过查找清单文件packageInstallerActivity中的意图过滤器,将setcategory(类别),setaction添加到意图对象中,指定data数据类型.
注意:如果同时有scheme和mimeType就要用setDataAndType(scheme(uri.parsefile(file)即可),mimetype).(这里的file并不是文件对象,要通过file.result获取)
③最后开启意图
8,自动更新的细节问题.
①如果版本是最新的,进入主界面速度太快,所以需要让splash界面暂停一段时间(套路)
SystemClock.sleep(xxxx);测试这个的时候,记得服务器版本和本地APP版本的区别
②如果用户没有点击对话框,点击别的地方,系统会默认关闭对话框,这时候界面就卡了,通过builder.setCancelable(false);//设置对话框不能被自动关闭.返回键也无效
③弹出了错误代码之后界面又卡了,这里需要让用户可以进入默认的主界面
④网络太差的时候,再睡两秒就不太合适了,这时候要去动态的获取时间,最开始获取一次时间,最后finally里再获取一次时间,判断两次时间的间隔,如果小于一定时间就睡眠一定时间(两秒减去间隔时间,如果大于两秒就直接进入主界面).
⑤代码优化,Message创建放到外面去,把handler.handlerMessage()放到finally里面必须执行.
9,应用程序的签名问题
直接从项目中拷贝的apk文件,是不能发布到应用市场的,因为没有进行签名,打开这个apk文件,可以看到META-INF,这个签名文件如果被修改,或资源文件被修改,都会导致应用程序的完整性得不到校验,无法再次安装,它的主要作用就是校验应用程序完整性.
eclipse会自动给一个调试debug的签名,它不能发布到市场上去,在应用程序的\META-INF\CERT.RSA文件中可以看到debug的字符串
创造一个签名,一般叫工程名.keystore,在导出项目的时候可以设置签名,设置的密码要保密,不让别人知道,点击next可以配置有效时间(最好大于25年),很多额外信息之类.
在导出项目的时候选择签名,输入密码即可
如果一个应用程序想要完成替换安装
签名一致,包名一致,一定要保存好keystore文件
10,制作主界面ui
预览的时候可以选择没有标题栏,和全屏的预览.
①TextView:希望文本一行显示:singleLine.
希望文本滚动,ellipsize设置marquee,但是直接定义这个属性是没效果的,它的底层可以看做是类似Web里字符串拼接截取达到的滚动效果,会消耗一定的资源,所以谷歌默认设置它没有焦点的时候就会生效.
做法:创建一个FocusTextView继承TextView,继承的时候最好继承所有的构造.
重写, isFocused(),返回一个ture即可.
使用自定义控件要在布局文件里写全路径名,框架才能找到它.
②记得给图标添加动画效果
③shimmer 土豪金文字效果
以上是关于手机卫士01的主要内容,如果未能解决你的问题,请参考以下文章