流程
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
}
}
打包
./gradlew app:assembleRelease
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);
}
}
}
使用L.d()输出日志
release包下不显示, Debug包下依旧有日志输出
加强 配置混淆文件proguard-rules.pro
-assumenosideeffects class android.util.Log{
public static *** d(...);
}
去掉Log.d这一行代码并且注释掉
#-dontoptimize
但是会增加apk闪退风险
使用jadx反编译
若某个类因为混淆而找不到则添加
-keep class android.support.**{
*;
}
3.minsdk,maxsdk,uses-feature组件安全
minsdk可以参考官方的版本分布,可以参考大厂的app,拖到as里看看manifest文件。minsdk过大,无法在低版本设备上安装
targetSdk和compileSdk保持一致
过滤下载权限
<uses-feature android:required="true" android:name="android.hardware.camera"/>
将一些敏感的组件不希望被外部启动的设为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'
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);
}
}
运行导致内存泄漏的代码
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();
}
}
消除方式
取消线程匿名内部类对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();
}
}
}
}
6.利用gradle 去打多渠道包
AndroidManifest.xml
<meta-data android:value="${UMENG_CHANNEL_VALUE}" android:name="UMENG_CHANNEL"/>
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"]
}
}