手机卫士01_业务分包,splash,packageInfo ,版本控制,替换安装,签名

开题:手机卫士这样的一个项目能够很好的复习基础所学的知识点,由于它覆盖面广,用来作安卓深刻学习是一个很好的选择.java

1,开始一个项目android

写一个好的代码不只是看功能是否实现,并且代码具备较高的可读性程序员

1.1 代码组织方式:web

①采用业务逻辑模块组织代码,以小米阅读为例:数据库

功能一:阅读器reader com.xiaomi.readerjson

功能二:分享 share com.xiaomi.sharewindows

功能三:便签 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 土豪金文字效果

相关文章
相关标签/搜索