手机卫士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数据类型.

注意:如果同时有schememimeType就要用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的主要内容,如果未能解决你的问题,请参考以下文章

安卓手机卫士第一天(要点)

手机卫士开发记录之handler错误

Android 项目实战--手机卫士(实现splash)

Android 手机卫士16--手机杀毒

[android] 手机卫士项目

Android 手机卫士--阶段小结1