体积缩小,apk打包去掉无用资源,启动优化,后台任务处理,白屏处理,混淆,ViewPager+fragment优化等过程
混淆模板
使用:直接复制到app/proguard-rules.pro文件中即可,处理混淆时根据第三方提供的混淆代码不从到其中,以及实体类保持等
- 减少apk体积
- 避免无用的资源编译到apk文件中
- 安全性
#-------------------------------------------定制化区域----------------------------------------------
#---------------------------------1.实体类---------------------------------
-keep class com.face.factoryageing.entity.** { *; }
#-------------------------------------------------------------------------
#---------------------------------2.第三方包-------------------------------
#eventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keep public class cn.jzvd.JZMediaSystem {*; }
-keep public class cn.jzvd.demo.CustomMedia.CustomMedia {*; }
-keep public class cn.jzvd.demo.CustomMedia.JZMediaIjk {*; }
-keep public class cn.jzvd.demo.CustomMedia.JZMediaSystemAssertFolder {*; }
-keep class tv.danmaku.ijk.media.player.** {*; }
-dontwarn tv.danmaku.ijk.media.player.*
-keep interface tv.danmaku.ijk.media.player.** { *; }
#log4j
#-------------------------------------------------------------------------
#---------------------------------3.与js互相调用的类------------------------
-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {
<methods>;
}
#-------------------------------------------------------------------------
#---------------------------------4.反射相关的类和方法-----------------------
# 有
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
#-------------------------------------------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field
public class InitializeService extends IntentService {
private static final String TAG="InitializeService";
private static final String ACTION_INIT_WHEN_APP_CREATE = "com.anly.githubapp.service.action.INIT";
public InitializeService() {
super("InitializeService");
}
public static void start(Context context) {
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INIT_WHEN_APP_CREATE);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {
performInit();
}
}
}
private void performInit() {
//在这里进行初始化的相关代码
KLog.init(true);
KLog.d(TAG,"performInit");
//CrashHandler.getInstance().init(this);
//CrashHandler.getInstance().init(getApplication());
//KLog.d("performInit begin:" + System.currentTimeMillis());
//需要在 Application 的 onCreate() 中调用一次 BaseIotTools.instance()....
//1080,1920是为了适配而去设置相关的值
//设置宽度|高度布局尺寸 layout 布局文件以pt为单位 setBaseScreenParam(1080,1920,true)
BaseIotUtils.instance().
setBaseScreenParam(1080,1920,true).
setCreenType(SCREEN_TYPE.WIDTH).//按照宽度适配
create(getApplication());
}
}
Activity启动优化
Activity只负责界面基础view初始化操作,耗时任务在异步任务中操作,互不干扰,避免UI产生卡顿
public class StartPageAty extends BaseActivity {
private static final String TAG="StartPageAty";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//先进入启动页,什么都不做,只是做一个跳转
startActivity(new Intent(StartPageAty.this, MainActivity.class));
}
@Override
protected void onDestroy() {
super.onDestroy();
try{
boolean isFrist= SPUtils.getBoolean("isFirst",true);
if(isFrist){
//如果是第一次进来
SPUtils.putBoolean("isFirst",false);
}else{
//如果是第二次及以后进来
}
}catch(Exception e){
e.printStackTrace();
KLog.e(TAG,"errMeg:"+e.getMessage());
}
}
}
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动完毕之后结束开始页
AppManager.getAppManager().finishActivity(StartPageAty.class);
//耗时任务放到线程中执行
new Handler().post(new Runnable() {
@Override
public void run() {
//这里异步执行耗时任务
List<File> fileList=getFileList();
}
});
}
}
drawable/logo_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 底层白色 -->
<item android:drawable="@color/white" />
<!-- 顶层Logo居中 -->
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/app_img" />
</item>
</layer-list>
res/values/styles.xml中添加
<!--
一:AndroidManifest.xml application中的theme使用该主题
二:启动成功后再Aty中设置为正常的主题
三:其他Aty设置为正常的AppTheme
这样打开桌面图标会马上显示logo,不会出现黑/白屏,
直到Activity启动完成,替换主题,logo消失,
-->
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">@drawable/logo_splash</item>
<item name="android:windowFullscreen">true</item>
</style>
内存申请及启动页配置
activity_main布局文件推荐使用RelativeLayout,可对耗时有一部分优化,尽量减少布局层次,嵌套等复杂布局。
AndroidManifest.xml中 android:largeHeap="true"分配更多内存提供给apk使用
<manifest>
<application
android:largeHeap="true"
android:persistent="true">
<!--启动页-->
<activity
android:name=".startpage.StartPageAty"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--首页-->
<activity android:name=".startpage.MainActivity"/>
<!--在服务里面进行一些application应该执行的初始化操作-->
<service android:name=".myapplication.InitializeService" />
</application>
</manfiest>
Fragment+ViewPager优化
将项目中的Fragment继承LazyLoadFragment实现懒加载
public abstract class LazyLoadFragment extends Fragment {
protected boolean isInit = false;
protected boolean isLoad = false;
protected final String TAG = "LazyLoadFragment";
private View view;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(setContentView(), container, false);
isInit = true;
isCanLoadData();
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isCanLoadData();
}
private void isCanLoadData() {
if (!isInit) {
return;
}
if (getUserVisibleHint()) {
lazyLoad();
isLoad = true;
} else {
if (isLoad) {
stopLoad();
}
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
isInit = false;
isLoad = false;
}
protected abstract int setContentView();
protected View getContentView() {
return view;
}
protected <T extends View> T findViewById(int id) {
return (T) getContentView().findViewById(id);
}
protected abstract void lazyLoad();
protected void stopLoad() {
}
}