欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发必知必会的27个知识点

程序员文章站 2022-03-26 20:07:46
> 1.ant打包完成:andresguard(微信资源包混淆) > 2.jenkins项目自动化(自动化构建android项目) > 3.sqlitecipher > 4....

> 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);

            }

        }