Android开发必知必会的27个知识点
> 1.ant打包完成:andresguard(微信资源包混淆)
> 2.jenkins项目自动化(自动化构建android项目)
> 3.sqlitecipher
> 4.https(服务器配置+客户端编程):银行、金融领域使用,
> 5.逆向编程:在加密算法安全领域使用,解决陌生类编码
> 6.leakcanary:分析检测内存泄漏(支付宝、淘宝、京东商城)
> 7.二维码:zxing,扫描+生成
### 01.android打包流程
> 1.生成r文件-> r.java,调用sdk的aapt.exe
> 2.编译aidl->生成java文件,调用aidl.exe
> 3.编译java文件 -> 生成class文件,调用1.7jdk的javac
> 4.解压第三方jar包 -> 生成class文件,调用jdk的jar
> 5.生成classes.dex文件,调用sdk的dx.bat
> 6.编译资源文件,生成resources.ap_,调用aapt
> 7.生成未签名apk,调用apkbuilder
> 8.生成签名apk,使用keystore
### 02.微信资源包混淆介绍
> 微信资源包混淆项目:[https://github.com/shwenzhang/andresguard](https://github.com/shwenzhang/andresguard)
![](img/tu16.png)
> 资源包混淆作用
* 1.避免其他人拷贝图片资源
* 2.把apk变小(apk瘦身步骤)
> 开发中到底用不用:看需求,可以使用资源包混淆,
### 03.微信资源包混淆andresguard常用命令
> 1.配置config.xml文件
<issue id="sign" isactive="true">
<!--the signature file path, in window use \, in linux use /, and the default path is the running location-->
<path value="e:\heima104\day2\mobilesafe\meituan.jks"/>
<!--storepass-->
<storepass value="123456"/>
<!--keypass-->
<keypass value="123456"/>
<!--alias-->
<alias value="meituan"/>
</issue>
> 2.简单命令(对签名和未签名apk都可以)
java -jar andresguard.jar ..\build\mobilesafe_signed.apk
> 3.指定配置文件或输出目录
java -jar andresguard.jar ..\build\mobilesafe_signed.apk -config config.xml -out heima
> 4.使用7zip打包
java -jar andresguard.jar ..\build\mobilesafe_signed.apk -config config.xml
-7zip 7za.exe -out heima_new
### 04.ant打包手机卫士-集成andresguard
<!-- 任务9:集成微信资源包混淆andresguard -->
<target name="andresguard" depends="generateunsignedapk">
<echo message="任务9:微信资源包混淆"/>
<exec executable="${java.exe}">
<arg value="-jar"/>
<arg value="${andresguard.jar}"/>
<arg value="${unsignedapk}"/>
<arg value="-config"/>
<arg value="${config.xml}"/>
<arg value="-out"/>
<arg value="${resguardout}"/>
</exec>
</target>
### 05.jenkins安装
> jenkins网站:[https://jenkins.io/](https://jenkins.io/)
> 安装:资料/jenkins.msi
> 安装完成:自动打开使用8080端口
### 06.jenkins配置
> 修改端口号,不能使用8080
> 打开安装目录jenkins.xml
--httpport=18080
> 重启服务器
> 系统管理/系统设置:配置jdk和ant环境
![](img/tu17.png)
### 07.jenkins项目自动化-项目提交到svn
> 1.visulsvn服务器:创建仓库
> 2.svn checkout:和svn服务器关联
> 3.文件添加到版本控制
> 4.commit提交到服务器
### 08.jenkins项目自动化-项目配置
> 1.使用jdk
> 2.管理svn版本服务器仓库地址:通过用户名/密码授权
> 3.使用ant构建:选择任务名
### 09.jenkins项目自动化-手动构建
![](img/tu18.png)
> 1.从svn服务器检出代码
### 10.android项目版本更新周期
> 多长时间更新一次版本:
标准:1个月、一个多月更新一次
遇到节节假日:比如双十一,发布活动版本,可能周期更快
不标准:1周更新一次、一天更新,不建议(用户体验差)
### 11.jenkins项目自动化-自动构建
> 定时打包:构建触发器/设置构建周期(最快频率2分钟)
> 需要获取输出apk文件:配置存档文件
### 11.jenkins项目自动化-自动构建(2)
> 遇到构建失败,配置存档文件**/*.apk报红色警告,重新创建新项目(不要重名)
### 12.https介绍
> 访问安全网站ca结构校验是否安全
> ca:授权机构,赛门铁克、交钱认证https网站
> 实现山寨百度,是https
### 13.https服务器配置
> 如何把一个http编程https安全网站
> tomcat文档:[https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html](https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html)
> 配置https的keystore
apache-tomcat-7.0.72\conf\server.xml
<connector port="8443" protocol="org.apache.coyote.http11.http11protocol"
maxthreads="150" sslenabled="true" scheme="https" secure="true"
keystorefile="conf/meituan.jks" keystorepass="123456"
clientauth="false" sslprotocol="tls" />
### 13.https客户端编程-信任管理器
//通过信任管理器工厂生成管理器
trustmanagerfactory tfm = trustmanagerfactory.getinstance(trustmanagerfactory.getdefaultalgorithm());
//为了能够访问没有认证的https网站,
// 需要设置信任管理器(相当于保安)
//1.创建安全上下文对象:看api文档
sslcontext context = sslcontext.getinstance("tls");
//2.管理信任管理器
trustmanager[] tm = tfm.gettrustmanagers();
context.init(null, tm, null);//逆向编程:先写对象,通过快捷键创建对应类型
httpsurlconnection conn = (httpsurlconnection) new url("https://10.0.2.2:8443/heima.json").openconnection();
ins = conn.getinputstream();
//使用信任管理器
conn.setsslsocketfactory(context.getsocketfactory());
### 15.https客户端编程-导出证书
> 通过keystore导出证书
keytool -exportcert -alias meituan -file meituan.cer -keystore meituan.jks
### 16.https客户端编程-使用证书
trustmanagerfactory tfm = trustmanagerfactory.getinstance(trustmanagerfactory.getdefaultalgorithm());
keystore ks = keystore.getinstance(keystore.getdefaulttype());
certificatefactory cf = certificatefactory.getinstance("x.509");
ks.load(null);//清空默认证书信息
inputstream certin = getassets().open("meituan.cer");
certificate cert = cf.generatecertificate(certin);//证书对象
certin.close();
ks.setcertificateentry("meituan", cert);
tfm.init(ks);//初始化信任管理器工厂
### 17.sqlite数据库加密介绍
> 正式项目有数据:缓存数据到本地(文件、db)
> qq联系人、微信聊天记录
> 不加密:神庙逃亡(绿砖,死亡复活),损失非常大,
### 18.sqlite数据库-不加密
/**
* 添加到数据库
* @param v
*/
public void insert(view v) {
string content = met.gettext().tostring().trim();
baseopenhelper openhelper = new baseopenhelper(mcontext);
sqlitedatabase db = openhelper.getwritabledatabase();
contentvalues values = new contentvalues();
values.put("username", content);
db.insert("t_user",null, values);
db.close();
//清空内容
met.settext("");
}
/**
* 查询
* @param v
*/
public void query(view v) {
baseopenhelper openhelper = new baseopenhelper(mcontext);
sqlitedatabase db = openhelper.getreadabledatabase();
cursor cursor = db.query("t_user", new string[]{"username"}, null, null, null, null, null);
if(cursor != null){
while(cursor.movetonext()){
//遍历数据
string username = cursor.getstring(0);
system.out.println(username);
}
cursor.close();
}
db.close();
}
### 18.sqlite数据库加密实现
> sqlite数据库加密项目:[https://github.com/sqlcipher/sqlcipher](https://github.com/sqlcipher/sqlcipher)
![](img/tu19.png)
> 不能使用android sqlite包名,使用别人的
> 获取sqlitedatabase需要传入密码
string content = met.gettext().tostring().trim();
baseopenhelper openhelper = new baseopenhelper(mcontext);
sqlitedatabase db = openhelper.getwritabledatabase(password);
contentvalues values = new contentvalues();
values.put("username", content);
db.insert("t_user",null, values);
db.close();
//清空内容
met.settext("");
### 19.leakcanary检测内存泄漏介绍
> 内存泄漏和内存溢出
内存泄漏:水龙头漏水,一滴一滴
内存溢出:盆接水,盆满了溢出,oom
> 为什会泄漏内:退出页面,对象没有被及时回收
### 20.leakcanary集成依赖
> 支付宝/设置/关于/版权信息:里面有开源项目leakcanary
> 多使用开源项目:提供开发效率
> 添加依赖:
debugcompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
releasecompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
> 出现入口application初始化
private context context;
public static refwatcher getrefwatcher(context context) {
galaxyapplication application = (galaxyapplication) context.getapplicationcontext();
return application.refwatcher;
}
private refwatcher refwatcher;
@override
public void oncreate() {
super.oncreate();
//初始化leak
if (leakcanary.isinanalyzerprocess(this)) {
// this process is dedicated to leakcanary for heap analysis.
// you should not init your app in this process.
return;
}
refwatcher = leakcanary.install(this);
}
### 21.leakcanary检测内存分析
> 基类检测内存泄漏
refwatcher refwatcher = galaxyapplication.getrefwatcher(getcontext());
refwatcher.watch(this);
![](img/tu20.png)
### 22.leakcanary-单例导致的内存泄漏
> leakcanary上线前分析内存,不能发布上线
> 解决方案:应用上线不能出现leakcanary图标,没有leakcanary 吐司
> 使用版本控制分支解决
> 1.初始化git
git init
git add .
git commit -m "first commit"
> 2.创建新的分支:专门用户集成leak项目
### 23.内存泄漏产生原因
> 1.不要过多使用static成员变量:基本数据类型可以static,对象数据类型不建议static
> 2.context不建议static,如果使用static指向application
> 3.数据库用完关闭
> 4.cursor使用完关闭
> 5.流使用完成关流
### 24.二维码zxing使用-集成zxing
> 参考文档:[https://github.com/open-android/zxing](https://github.com/open-android/zxing)
### 25.二维码zxing使用-生成二维码
public void gencode(view v) {
string content = met.gettext().tostring().trim();
bitmap bitmap = null;
try {
bitmap = bitmaputils.create2dcode(content);
miv.setimagebitmap(bitmap);
} catch (writerexception e) {
e.printstacktrace();
}
}
### 26.二维码zxing使用-扫码
public void scan(view v){
//startactivity(new intent(mainactivity.this, captureactivity.class));
//扫描完成获取结果
intent intent = new intent(mainactivity.this, captureactivity.class);
startactivityforresult(intent, reqcode_scan);
}
@override
protected void onactivityresult(int requestcode, int resultcode, intent data) {
super.onactivityresult(requestcode, resultcode, data);
//获取返回结果
string result = data.getstringextra("qrcode_result");
toast.maketext(this, ""+result, toast.length_long).show();
if(requestcode == reqcode_scan){
/* string result = data.getstringextra("qrcode_result");
toast.maketext(this, ""+result, toast.length_long).show();*/
}
}
### 27.二维码zxing使用-处理扫码结果
if(requestcode == reqcode_scan){
/* string result = data.getstringextra("qrcode_result");
toast.maketext(this, ""+result, toast.length_long).show();*/
string result = data.getstringextra("qrcode_result");
toast.maketext(this, "" + result, toast.length_long).show();
if(result.contains("https://")){
//网站:浏览器打开,隐式意图打开
/* <intent-filter>
<action android:name="android.intent.action.view" />
<category android:name="android.intent.category.default" />
<category android:name="android.intent.category.browsable" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="about" />
<data android:scheme="javascript" />
</intent-filter>*/
intent intent = new intent();
intent.setaction("android.intent.action.view");
intent.addcategory("android.intent.category.default");
intent.addcategory("android.intent.category.browsable");
intent.setdata(uri.parse("http:" + result));
startactivity(intent);
}
}