• apk打包基本流程


    流程

    1.生成签名,设置混淆配置,打release包

    请添加图片描述

    在build.gradle中写入

    signingConfigs{
        release{
            storeFile file("绝对路径")
            storePassword "签名密码"
            keyAlias "密钥别名"
            keyPassword "密钥密码"
        }
        debug{
            storeFile file("绝对路径")
            storePassword "签名密码"
            keyAlias "密钥别名"
            keyPassword "密钥密码"
        }
    }
    
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    打包

    ./gradlew app:assembleRelease
    
    • 1

    2.Log的问题

    添加辅助类

    public class L {
    
        public static boolean isDebug = BuildConfig.DEBUG;
    
        public static void d(String tag,String msg){
            if (isDebug) {
                Log.d(tag,msg);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用L.d()输出日志

    release包下不显示, Debug包下依旧有日志输出

    加强 配置混淆文件proguard-rules.pro

    -assumenosideeffects class android.util.Log{
        public static *** d(...);
    }
    
    • 1
    • 2
    • 3

    去掉Log.d这一行代码并且注释掉

    #-dontoptimize
    
    • 1

    但是会增加apk闪退风险

    使用jadx反编译

    若某个类因为混淆而找不到则添加

    -keep class android.support.**{
            *;
    }
    
    • 1
    • 2
    • 3

    3.minsdk,maxsdk,uses-feature组件安全

    minsdk可以参考官方的版本分布,可以参考大厂的app,拖到as里看看manifest文件。minsdk过大,无法在低版本设备上安装

    targetSdk和compileSdk保持一致
    
    • 1

    过滤下载权限

    <uses-feature android:required="true" android:name="android.hardware.camera"/>
    
    • 1

    将一些敏感的组件不希望被外部启动的设为android:exported=“false”

    4.接入友盟SDK,SDK后台

    友盟+,国内领先的开发者服务及数据智能服务商 (umeng.com)

    5.LeakCanary检测内存泄漏

    添加依赖

    implementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
    implementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
    
    • 1
    • 2
    package com.example.synthesisdemo;
    
    import android.app.Application;
    
    
    import com.squareup.leakcanary.LeakCanary;
    import com.umeng.analytics.MobclickAgent;
    import com.umeng.commonsdk.UMConfigure;
    
    public class MyApp extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            /**
             *   注意: 即使您已经在AndroidManifest.xml中配置过appkey和channel值,也需要在App代码中调 * 用初始化接口(如需要使用AndroidManifest.xml中配置好的appkey和channel值, * UMConfigure.init调用中appkey和channel参数请置为null)。
             */
    
            if(LeakCanary.isInAnalyzerProcess(this)){
                return;
            }
            LeakCanary.install(this);
            UMConfigure.setLogEnabled(BuildConfig.DEBUG);
            UMConfigure.init(this,UMConfigure.DEVICE_TYPE_PHONE,null);
    
            MobclickAgent.setScenarioType(this, MobclickAgent.EScenarioType.E_UM_NORMAL);
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    运行导致内存泄漏的代码

    public class aaa extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            new Thread(()->{
                try {
                    TimeUnit.SECONDS.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"assa").start();
        }
        
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    消除方式

    取消线程匿名内部类对activity的引用

    package com.example.synthesisdemo;
    
    import android.os.Bundle;
    
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    
    import java.util.concurrent.TimeUnit;
    
    public class aaa extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
                new testa("assa");
        }
    
        public static class testa extends Thread{
            public testa(String name){
                super(name);
            }
    
            @Override
            public void run() {
                super.run();
                try {
                    TimeUnit.SECONDS.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    6.利用gradle 去打多渠道包

    AndroidManifest.xml

    <meta-data android:value="${UMENG_CHANNEL_VALUE}" android:name="UMENG_CHANNEL"/>
    
    • 1

    build.gradle

    flavorDimensions "market"
    productFlavors{
        baidu{
            manifestPlaceholders = [UMENG_CHANNEL_VALUE:"baidu"]
        }
        yingyongbao{
            manifestPlaceholders = [UMENG_CHANNEL_VALUE:"yingyongbao"]
        }
        _360{
            manifestPlaceholders = [UMENG_CHANNEL_VALUE:"_360"]
        }
        wandoujia{
            manifestPlaceholders = [UMENG_CHANNEL_VALUE:"wandoujia"]
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    7.上传git

  • 相关阅读:
    【JavaScript】巩固JS开发中十个常用功能/案例(21-30)(牛客题解)
    Vue3 ref响应式变量详解
    音视频从入门到精通——FFmpeg分离出PCM数据实战
    Git 命令行查看仓库信息
    Spring-boot-starter-actuator的可视化spring-boot-admin
    JS中的元素样式
    在创建的关于tensorflow的envs环境中无法import出pip中显示的包
    记一次 .NET 某外贸ERP 内存暴涨分析
    SSM - Springboot - MyBatis-Plus 全栈体系(十八)
    新能源汽车高压上电、高压下电逻辑分析
  • 原文地址:https://blog.csdn.net/liuwushuang233/article/details/126489449