这篇文章是将好久以来看过的文章,包括本身写的一些测试代码的总结.属于笔记的性质,没有面面俱到,一些本身相对熟悉的点可能会略过.
最开始看到的性能优化的文章,就是胡凯的优化典范系列,后来又陆续看过一些人写的,我的以为anly_jun和胡凯的质量最好.
文章大的框架也是先把优化典范过一遍,记录我的认为重要的点,而后是anly_jun的系列,将以前未覆盖的补充进去,也包括HenCoder的一些课程相关内容.
固然除了上面几位,还有不少其余大神的文章,时间久了也记不太清,在此一并谢过.javascript
Overdraw过分绘制是指屏幕上的某个像素在同一帧的时间内被绘制了屡次.过分绘制会大量浪费CPU及GPU资源/占用CPU和GPU的处理时间php
public class OverdrawView extends View {
public OverdrawView(Context context) {
super(context);
init();
}
public OverdrawView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public OverdrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap bitmap1,bitmap2,bitmap3;
private void init(){
paint.setStyle(Paint.Style.FILL);
bitmap1 = BitmapFactory.decodeResource(getResources(),R.mipmap.png1);
bitmap2 = BitmapFactory.decodeResource(getResources(),R.mipmap.png2);
bitmap3 = BitmapFactory.decodeResource(getResources(),R.mipmap.png3);
}
int w,h;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
w = getMeasuredWidth();
h = getMeasuredHeight();
}
private boolean Overdraw = true;
@Override
protected void onDraw(Canvas canvas) {
if(Overdraw){
//默认会出现过分绘制
canvas.drawBitmap(bitmap1,0,0,paint);
canvas.drawBitmap(bitmap2,w/3,0,paint);
canvas.drawBitmap(bitmap3,w*2/3,0,paint);
}else{
//使用Canvas.clipRect避免过分绘制
canvas.save();
canvas.clipRect(0,0,w/3,h);
canvas.drawBitmap(bitmap1,0,0,paint);
canvas.restore();
canvas.save();
canvas.clipRect(w/3,0,w*2/3,h);
canvas.drawBitmap(bitmap2,w/3,0,paint);
canvas.restore();
canvas.save();
canvas.clipRect(w*2/3,0,w,h);
canvas.drawBitmap(bitmap3,w*2/3,0,paint);
canvas.restore();
}
}
//切换是否避免过分绘制
public void toggleOverdraw(){
Overdraw = !Overdraw;
invalidate();
}
}
复制代码
效果图:html
内存泄漏就是无用对象占据的内存空间没有及时释放,致使内存空间浪费的状况.memory leak.
内存溢出是App为1个对象申请内存空间,内存空间不足的状况.out of memory.
内存泄漏数量足够大,就会引发内存溢出.或者说内存泄漏是内存溢出的缘由之一.java
public class User {
public String id;
public String name;
//对象池实例
private static final SynchronizedPool<User> sPool = new SynchronizedPool<User>(10);
public static User obtain() {
User instance = sPool.acquire();
return (instance != null) ? instance : new User();
}
public void recycle() {
sPool.release(this);
}
}
复制代码
public class ForTest {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>();
ArrayList<Integer> a = new ArrayList<>();
LinkedList<Integer> l = new LinkedList<>();
int time = 1000000;
for(int i = 0; i< time; i++){
Integer item = new Random().nextInt(time);
v.add(item);
a.add(item);
l.add(item);
}
//测试3种遍历性能
long start = System.currentTimeMillis();
for(int i = 0;i<v.size();i++){
Integer item = v.get(i);
}
long end = System.currentTimeMillis();
System.out.println("for index Vector耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(int i = 0;i<a.size();i++){
Integer item = a.get(i);
}
end = System.currentTimeMillis();
System.out.println("for index ArrayList耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(int i = 0;i<l.size();i++){
Integer item = l.get(i);
}
end = System.currentTimeMillis();
System.out.println("for index LinkedList耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Integer item:v){
Integer i = item;
}
end = System.currentTimeMillis();
System.out.println("for simple Vector耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Integer item:a){
Integer i = item;
}
end = System.currentTimeMillis();
System.out.println("for simple ArrayList耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Integer item:l){
Integer i = item;
}
end = System.currentTimeMillis();
System.out.println("for simple LinkedList耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Iterator i = v.iterator();i.hasNext();){
Integer item = (Integer) i.next();
}
end = System.currentTimeMillis();
System.out.println("for Iterator Vector耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Iterator i = a.iterator();i.hasNext();){
Integer item = (Integer) i.next();
}
end = System.currentTimeMillis();
System.out.println("for Iterator ArrayList耗时:"+(end-start)+"ms");
start = System.currentTimeMillis();
for(Iterator i = l.iterator();i.hasNext();){
Integer item = (Integer) i.next();
}
end = System.currentTimeMillis();
System.out.println("for Iterator LinkedList耗时:"+(end-start)+"ms");
}
}
打印结果:
for index Vector耗时:28ms
for index ArrayList耗时:14ms
LinkedList就不能用for index方式进行遍历.
for simple Vector耗时:68ms
for simple ArrayList耗时:11ms
for simple LinkedList耗时:34ms
for Iterator Vector耗时:49ms
for Iterator ArrayList耗时:12ms
for Iterator LinkedList耗时:0ms
复制代码
能够将merge当作1个ViewGroup v,若是v的类型和v的父控件的类型一致,那么v其实不必存在,由于白白增长了布局的深度.因此merge使用时必须保证merge中子控件所应该在的ViewGroup类型和merge所在的父控件类型一致.python
Merge的使用场景有2个:android
代码示例
merge做为根布局的布局文件,用于Activity的setContentView:git
activity_merge.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="0dp" android:text="111111" />
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="100dp" android:layout_marginLeft="40dp" android:text="222222" />
</merge>
复制代码
activity_merge_include.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="merge被include引用" />
<include layout="@layout/activity_merge" />
</LinearLayout>
复制代码
@Override
public boolean hasOverlappingRendering() {
return false;
}
复制代码
View v = findViewById(R.id.root);
//经过setLayerType的方法来指定View应该如何进行渲染
//开启硬件加速
v.setLayerType(View.LAYER_TYPE_HARDWARE,null);
v.setAlpha(0.60F);
//透明度设置完毕后关闭硬件加速
v.setLayerType(View.LAYER_TYPE_NONE,null);
复制代码
public class MainActivity extends Activity {
//1:首先定义常量
public static final int MALE = 0;
public static final int FEMALE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Person person = new Person();
person.setSex(MALE);
((Button) findViewById(R.id.test)).setText(person.getSexDes());
}
class Person {
//3.为指定的属性及方法添加自定义注解
@SEX
private int sex;
//3.为指定的属性及方法添加自定义注解
public void setSex(@SEX int sex) {
this.sex = sex;
}
//3.为指定的属性及方法添加自定义注解
@SEX
public int getSex() {
return sex;
}
public String getSexDes() {
if (sex == MALE) {
return "男";
} else {
return "女";
}
}
}
//2:而后建立自定义注解,设置取值范围就是刚刚定义的常量,并设置自定义注解的保留范围是源码时
@IntDef({MALE, FEMALE})
@Retention(RetentionPolicy.SOURCE)
public @interface SEX {
}
}
复制代码
在onDestroy调用Handler.removeCallbacksAndMessages(null)移除该Handler关联的全部Message及Runnable.再发生GC,Message已经不存在,就能够顺利的回收Handler及Activitygithub
@Override
protected void onDestroy() {
super.onDestroy();
m.removeCallbacksAndMessages(null);
}
复制代码
自定义静态内部类继承Handler,静态内部类实例不持有外部Activity的引用.在自定义Handler中定义外部Activity的弱引用,只有弱引用关联的外部Activity实例未被回收的状况下才继续执行handleMessage.自定义Handler持有外部Activity的弱引用,发生GC时不耽误Activity被回收.web
static class M extends Handler{
WeakReference<Activity> mWeakReference;
public M(Activity activity) {
mWeakReference=new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
if(mWeakReference != null){
Activity activity=mWeakReference.get();
if(activity != null){
if(msg.what == 15){
Toast.makeText(activity,"M:15",Toast.LENGTH_SHORT).show();
}
if(msg.what == 5){
Toast.makeText(activity,"M:5",Toast.LENGTH_SHORT).show();
}
}
}
}
}
private M m;
@Override
protected void onResume() {
super.onResume();
m = new M(this);
m.sendMessageDelayed(m.obtainMessage(15),15000);
m.sendMessageDelayed(m.obtainMessage(5),5000);
}
复制代码
在避免内存泄漏的前提下,若是要求Activity退出就不执行后续动做,用方法1.若是要求后续动做在GC发生前继续执行,使用方法2算法
public class IntentCheckActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent_check);
}
public void openSBTest(View view) {
// 跳转到"傻逼"软件
Intent sbIntent = new Intent("android.media.action.IMAGE_GO_SB");
if (sbIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sbIntent);
} else {
//会弹出这个提示
Toast.makeText(this,"设备木有傻逼!",Toast.LENGTH_SHORT).show();
}
}
public void openCameraTest(View view) {
// 跳转到系统照相机
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
startActivity(cameraIntent);
//正常设备会进入相机并弹出提示
Toast.makeText(this,"设备有相机!",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"设备木有相机!",Toast.LENGTH_SHORT).show();
}
}
}
复制代码
okHttp Picasso
MVP架构实现的Github客户端(4-加入网络缓存)
2.1.AS中生成keystore.jks应用于APK打包
1:生成keystore.jks
2:查看.jks文件的SHA1安全码
在AS的Terminal中输入:
keytool -list -v -keystore C:\Users\Administrator\Desktop\key.jks
keytool -list -v -keystore .jks文件详细路径
回车后,输入密钥库口令/就是.jks的密码,输入过程不可见,输入完毕回车便可!
2.2.proguard-rules关键字及部分通配符含义
关键字 | 描述 |
keep | 保留类和类中的成员,防止它们被混淆或移除 |
keepnames | 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除 |
keepclasseswithmembers | 保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在,若是不存在则仍是会混淆 |
keepclasseswithmembernames | 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,若是不存在则仍是会混淆 |
keepclassmembers | 只保留类中的成员,防止它们被混淆或移除 |
keepclassmembernames | 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除 |
通配符 | 描述 |
< field > | 匹配类中的全部字段 |
< method > | 匹配类中的全部方法 |
< init > | 匹配类中的全部构造函数 |
* | 1.*和字符串联合使用,*表明任意长度的不包含包名分隔符(.)的字符串: a.b.c.MainActivity: a.*.*.MainActivity能够匹配;a.*就匹配不上; 2.*单独使用,就能够匹配全部东西 |
** | 匹配任意长度字符串,包含包名分隔符(.) a.b.**能够匹配a.b包下全部内容,包括子包 |
*** | 匹配任意参数类型.好比: void set*(***)就能匹配任意传入的参数类型; *** get*()就能匹配任意返回值的类型 |
… | 匹配任意长度的任意类型参数.好比: void test(…)就能匹配任意void test(String a)或者是void test(int a, String b) |
-keep public class a.b.c.TestItem{
*;
}
复制代码
-keep public class a.**.Bean.**{
public void set*(***);
public *** get*();
# 对应获取boolean类型属性的方法
public *** is*();
}
复制代码
#保留单个包含反射代码的类
-keep public class a.b.c.ReflectUtils{
*;
}
#保留全部包含反射代码的类,好比全部涉及反射代码的类都在a.b.reflectpackage包及其子包下
-keep class a.b.reflectpackage.**{
*;
}
复制代码
-keep class * extends a.b.c.Parent{*;}
-keep class * implements a.b.c.OneInterface{*;}
复制代码
2.3.proguard-rules.pro通用模板
#####################基本指令##############################################
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile
#代码混淆压缩比,在0~7之间,默认为5,通常不须要改
-optimizationpasses 5
#混淆时不使用大小写混合,混淆后的类名为小写
-dontusemixedcaseclassnames
#指定不去忽略非公共的库的类
-dontskipnonpubliclibraryclasses
#指定不去忽略非公共的库的类的成员
-dontskipnonpubliclibraryclassmembers
#不作预校验,preverify是proguard的4个步骤之一
#Android不须要preverify,去掉这一步可加快混淆速度
-dontpreverify
#有了verbose这句话,混淆后就会生成映射文件
#包含有类名->混淆后类名的映射关系
-verbose
#而后使用printmapping指定映射文件的名称
-printmapping mapping.txt
#指定混淆时采用的算法,后面的参数是一个过滤器,这个过滤器是谷歌推荐的算法,通常不改变
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护代码中的Annotation不被混淆,这在JSON实体映射时很是重要(保留注解参数)
-keepattributes *Annotation*
#避免混淆泛型,这在JSON实体映射时很是重要
-keepattributes Signature
#抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
#忽略全部警告
-ignorewarnings
###################须要保留的东西########################################
#保留反射的方法和类不被混淆================================================
#手动启用support keep注解
#http://tools.android.com/tech-docs/support-annotations
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
#==========================================================================================
#保留全部的本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
#保留了继承自Activity、Application这些类的子类
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class * extends com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}
#保留在Activity中的方法参数是view的方法,从而咱们在layout里面便携onClick就不会受影响
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
#枚举类不能被混淆
-keepclassmembers enum *{
public static **[] values();
public static ** valueOf(java.lang.String);
}
#保留自定义控件不被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
void set*(***);
*** get*();
}
#保留Parcelable序列化的类不被混淆
-keep class * implements android.os.Paracelable{
public static final android.os.Paracelable$Creator *;
}
#保留Serializable序列化的类的以下成员不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#对于R(资源)下的全部类及其方法,都不能被混淆
-keep class **.R$*{
*;
}
#R文件中的全部记录资源id的静态字段
-keepclassmembers class **.R$* {
public static <fields>;
}
#对于带有回调函数onXXEvent的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
}
#============================针对app的量身定制=============================================
# webView处理,项目中没有使用到webView忽略便可
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, java.lang.String);
}
复制代码
2.4.混淆jar包
郭霖大神博客有介绍,本身没试过
2.5.几条实用的Proguard rules
在上面提供的通用模板上继续添加下面几行:
-repackageclasses com
-obfuscationdictionary dict.txt
-classobfuscationdictionary dict.txt
-packageobfuscationdictionary dict.txt
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
复制代码
2.6.字符串硬编码
//1:新建常量类,用于存放字符串常量
public class HardStrings {
//2:名称是真正内容,值是难以理解的编码.
//这样即便是必须保存的Log,被反编译者看到的也只是难以理解的值,搞不清意义
public static final String MaxMemory = "001";
public static final String M = "002";
public static final String MemoryClass = "003";
public static final String LargeMemoryClass = "004";
public static final String 系统总内存 = "005";
public static final String 系统剩余内存 = "006";
public static final String 系统是否处于低内存运行 = "007";
public static final String 系统剩余内存低于 = "008";
public static final String M时为低内存运行 = "009";
}
复制代码
2.7.res资源混淆及多渠道打包
简单讲,使用腾讯的2个gradle插件来实现res资源混淆及多渠道打包.
res资源混淆:AndResGuard
多渠道打包:VasDolly
多渠道打包原理+VasDolly和其余多渠道打包方案对比
具体流程:
AndResGuard使用了chaychan的方法,单首创建gradle文件
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
//添加AndResGuard
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.12'
//添加VasDolly
classpath 'com.leon.channel:plugin:2.0.1'
}
}
复制代码
apply plugin: 'AndResGuard'
andResGuard {
mappingFile = null
use7zip = true
useSign = true
keepRoot = false
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"resources.arsc"
]
whiteList = [
// // your icon
// "R.drawable.icon",
// // for fabric
// "R.string.com.crashlytics.*",
// // for umeng update
// "R.string.tb_*",
// "R.layout.tb_*",
// "R.drawable.tb_*",
// "R.drawable.u1*",
// "R.drawable.u2*",
// "R.color.tb_*",
// // umeng share for sina
// "R.drawable.sina*",
// // for google-services.json
// "R.string.google_app_id",
// "R.string.gcm_defaultSenderId",
// "R.string.default_web_client_id",
// "R.string.ga_trackingId",
// "R.string.firebase_database_url",
// "R.string.google_api_key",
// "R.string.google_crash_reporting_api_key",
//
// //友盟
// "R.string.umeng*",
// "R.string.UM*",
// "R.layout.umeng*",
// "R.drawable.umeng*",
// "R.id.umeng*",
// "R.anim.umeng*",
// "R.color.umeng*",
// "R.style.*UM*",
// "R.style.umeng*",
//
// //融云
// "R.drawable.u*",
// "R.drawable.rc_*",
// "R.string.rc_*",
// "R.layout.rc_*",
// "R.color.rc_*",
// "R.id.rc_*",
// "R.style.rc_*",
// "R.dimen.rc_*",
// "R.array.rc_*"
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.12'
//path = "/usr/local/bin/7za"
}
}
复制代码
apply plugin: 'com.android.application'
//引入刚刚建立的and_res_guard.gradle
apply from: 'and_res_guard.gradle'
//依赖VasDolly
apply plugin: 'channel'
channel{
//指定渠道文件
channelFile = file("channel.txt")
//多渠道包的输出目录,默认为new File(project.buildDir,"channel")
baseOutputDir = new File(project.buildDir,"channel")
//多渠道包的命名规则,默认为:${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}
apkNameFormat ='${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}'
//快速模式:生成渠道包时不进行校验(速度能够提高10倍以上,默认为false)
isFastMode = true
//buildTime的时间格式,默认格式:yyyyMMdd-HHmmss
buildTimeDateFormat = 'yyyyMMdd-HH:mm:ss'
//低内存模式(仅针对V2签名,默认为false):只把签名块、中央目录和EOCD读取到内存,不把最大头的内容块读取到内存,在手机上合成APK时,可使用该模式
lowMemory = false
}
rebuildChannel {
//指定渠道文件
channelFile = file("channel.txt")
// baseDebugApk = new File(project.projectDir, "app-release_7zip_aligned_signed.apk")
baseReleaseApk = new File(project.projectDir, "app-release_7zip_aligned_signed.apk")
//默认为new File(project.buildDir, "rebuildChannel/debug")
// debugOutputDir = new File(project.buildDir, "rebuildChannel/debug")
//默认为new File(project.buildDir, "rebuildChannel/release")
releaseOutputDir = new File(project.buildDir, "rebuildChannel/release")
//快速模式:生成渠道包时不进行校验(速度能够提高10倍以上,默认为false)
isFastMode = false
//低内存模式(仅针对V2签名,默认为false):只把签名块、中央目录和EOCD读取到内存,不把最大头的内容块读取到内存,在手机上合成APK时,可使用该模式
lowMemory = false
}
android {
signingConfigs {
tcl {
keyAlias 'qinghailongxin'
keyPassword 'huanhailiuxin'
storeFile file('C:/Users/Administrator/Desktop/key.jks')
storePassword 'huanhailiuxin'
}
}
compileSdkVersion 28
defaultConfig {
applicationId "com.example.administrator.proguardapp"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
zipAlignEnabled true
pseudoLocalesEnabled true
proguardFiles 'proguard-rules.pro'
signingConfig signingConfigs.tcl
}
debug {
signingConfig signingConfigs.tcl
minifyEnabled true
pseudoLocalesEnabled true
zipAlignEnabled true
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-vector-drawable:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation files('libs/litepal-2.0.0.jar')
//依赖VasDolly
api 'com.leon.channel:helper:2.0.1'
}
复制代码
在Gradle界面中,找到app模块下andresguard的task.
将app-release_aligned_signed.apk放到app模块下,在Gradle界面中,找到app模块下channel的task,执行reBuildChannel指令.
String channel = ChannelReaderUtil.getChannel(getApplicationContext());
复制代码
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;
public class GzipRequestInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
@Override
public MediaType contentType() {
return body.contentType();
}
@Override
public long contentLength() {
return -1; // 没法提早知道压缩后的数据大小
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}
而后构建OkhttpClient的时候,添加拦截器:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new GzipRequestInterceptor())//开启Gzip压缩
...
.build();
复制代码
public final class ZipUtils {
/** * Gzip 压缩数据 * * @param unGzipStr * @return */
public static String compressForGzip(String unGzipStr) {
// if (TextUtils.isEmpty(unGzipStr)) {
// return null;
// }
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baos);
gzip.write(unGzipStr.getBytes());
gzip.close();
byte[] encode = baos.toByteArray();
baos.flush();
baos.close();
// return Base64Encoder.encode(encode);
return new String(encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/** * Gzip解压数据 * * @param gzipStr * @return */
public static String decompressForGzip(String gzipStr) {
// if (TextUtils.isEmpty(gzipStr)) {
// return null;
// }
// byte[] t = Base64Decoder.decodeToBytes(gzipStr);
byte[] t = gzipStr.getBytes();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(t);
GZIPInputStream gzip = new GZIPInputStream(in);
byte[] buffer = new byte[1024];
int n = 0;
while ((n = gzip.read(buffer, 0, buffer.length)) > 0) {
out.write(buffer, 0, n);
}
gzip.close();
in.close();
out.close();
return out.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/** * Zip 压缩数据 * * @param unZipStr * @return */
public static String compressForZip(String unZipStr) {
// if (TextUtils.isEmpty(unZipStr)) {
// return null;
// }
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(baos);
zip.putNextEntry(new ZipEntry("0"));
zip.write(unZipStr.getBytes());
zip.closeEntry();
zip.close();
byte[] encode = baos.toByteArray();
baos.flush();
baos.close();
// return Base64Encoder.encode(encode);
return new String(encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/** * Zip解压数据 * * @param zipStr * @return */
public static String decompressForZip(String zipStr) {
// if (TextUtils.isEmpty(zipStr)) {
// return null;
// }
// byte[] t = Base64Decoder.decodeToBytes(zipStr);
byte[] t = zipStr.getBytes();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(t);
ZipInputStream zip = new ZipInputStream(in);
zip.getNextEntry();
byte[] buffer = new byte[1024];
int n = 0;
while ((n = zip.read(buffer, 0, buffer.length)) > 0) {
out.write(buffer, 0, n);
}
zip.close();
in.close();
out.close();
return out.toString("UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public class GzipZipTest {
public static void main(String[] args) {
GzipZipTest t = new GzipZipTest();
t.t();
}
private void t(){
/*List<Person> l = new ArrayList<Person>(); for(int i=0;i<1;i++){ for(int j=0;j<6000;j++){ Person p = new Person(); p.age = j; p.gender = "gender"+j; p.name = "name"+j; l.add(p); } } Gson gson = new Gson(); List<String> names = new ArrayList<String>(); List<String> genders = new ArrayList<String>(); List<Integer> ages = new ArrayList<Integer>(); for(Person p:l){ names.add(p.name); genders.add(p.gender); ages.add(p.age); } PersonItemList itemList = new PersonItemList(); itemList.items = l; String jsonDataOri = gson.toJson(itemList); System.out.println("原始数据结构 压缩前json数据长度 ---->" + jsonDataOri.length()); PersonAttrList attrList = new PersonAttrList(); attrList.names = names; attrList.genders = genders; attrList.ages = ages; String jsonDataVariety = gson.toJson(attrList); System.out.println("变种数据结构 压缩前json数据长度 ---->" + jsonDataVariety.length()); System.out.println("==================================================="); for(int i=0;i<100;i++){ //1:原始数据结构 //Gzip压缩 long start = System.currentTimeMillis(); String gzipStr = ZipUtils.compressForGzip(jsonDataOri); long end = System.currentTimeMillis(); System.out.println("原始数据结构 Gzip压缩耗时 cost time---->" + (end - start)); System.out.println("原始数据结构 Gzip压缩后json数据长度 ---->" + gzipStr.length()); //Zip压缩 // start = System.currentTimeMillis(); // String zipStr = ZipUtils.compressForZip(jsonDataOri); // end = System.currentTimeMillis(); // System.out.println("原始数据结构 Zip压缩耗时 cost time---->" + (end - start)); // System.out.println("原始数据结构 Zip压缩后json数据长度 ---->" + zipStr.length()); //2:变种数据结构 //Gzip压缩 start = System.currentTimeMillis(); String gzipStrVariety = ZipUtils.compressForGzip(jsonDataVariety); end = System.currentTimeMillis(); System.out.println("变种数据结构 Gzip压缩耗时 cost time---->" + (end - start)); System.out.println("变种数据结构 Gzip压缩后json数据长度 ---->" + gzipStrVariety.length()); //Zip压缩 // start = System.currentTimeMillis(); // String zipStrVariety = ZipUtils.compressForZip(jsonDataVariety); // end = System.currentTimeMillis(); // System.out.println("变种数据结构 Zip压缩耗时 cost time---->" + (end - start)); // System.out.println("变种数据结构 Zip压缩后json数据长度 ---->" + zipStrVariety.length()); System.out.println("压缩后 原始结构长度:变种数据结构="+((float)gzipStr.length())/(float)gzipStrVariety.length()); System.out.println("==================================================="); }*/
float repetitionRatio = 0.00F;
List<Person> l = new ArrayList<Person>();
for(repetitionRatio = 0.000F; repetitionRatio < 0.500F; repetitionRatio+=0.005F){
int reportIndex = (int) (6000 * (1-repetitionRatio));
for(int i = 0;i<reportIndex;i++){
Person p = new Person();
p.age = i;
p.gender = "gender"+i;
p.name = "name"+i;
l.add(p);
}
if(repetitionRatio > 0.00F){
int reportCount = (int) (6000 * repetitionRatio);
for(int i = 0;i<reportCount;i++){
Person p = new Person();
p.age = i;
p.gender = "gender"+i;
p.name = "name"+i;
l.add(p);
}
}
Gson gson = new Gson();
List<String> names = new ArrayList<String>();
List<String> genders = new ArrayList<String>();
List<Integer> ages = new ArrayList<Integer>();
for(Person p:l){
names.add(p.name);
genders.add(p.gender);
ages.add(p.age);
}
PersonItemList itemList = new PersonItemList();
itemList.items = l;
String jsonDataOri = gson.toJson(itemList);
System.out.println("===================================================");
System.out.println("原始数据结构 压缩前json数据长度 ---->" + jsonDataOri.length());
PersonAttrList attrList = new PersonAttrList();
attrList.names = names;
attrList.genders = genders;
attrList.ages = ages;
String jsonDataVariety = gson.toJson(attrList);
System.out.println("变种数据结构 压缩前json数据长度 ---->" + jsonDataVariety.length());
//1:原始数据结构
//Gzip压缩
long start = System.currentTimeMillis();
String gzipStr = ZipUtils.compressForGzip(jsonDataOri);
long end = System.currentTimeMillis();
System.out.println("原始数据结构 Gzip压缩后json数据长度 ---->" + gzipStr.length());
//2:变种数据结构
//Gzip压缩
start = System.currentTimeMillis();
String gzipStrVariety = ZipUtils.compressForGzip(jsonDataVariety);
end = System.currentTimeMillis();
System.out.println("变种数据结构 Gzip压缩后json数据长度 ---->" + gzipStrVariety.length());
System.out.println("重复率为 "+repetitionRatio/(1-repetitionRatio)+" 压缩后:原始结构长度:变种数据结构="+((float)gzipStr.length())/(float)gzipStrVariety.length());
}
}
public class Person implements Serializable{
public String name;
public String gender;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class PersonItemList implements Serializable{
public List<Person> items;
public List<Person> getItems() {
return items;
}
public void setItems(List<Person> items) {
this.items = items;
}
}
public class PersonAttrList implements Serializable{
public List<String> names;
public List<String> genders;
public List<Integer> ages;
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
public List<String> getGenders() {
return genders;
}
public void setGenders(List<String> genders) {
this.genders = genders;
}
public List<Integer> getAges() {
return ages;
}
public void setAges(List<Integer> ages) {
this.ages = ages;
}
}
}
首先看当单个对象属性重复率超过100%的状况下打印结果:
List<Person> l = new ArrayList<Person>();
for(int i=0;i<1;i++){
for(int j=0;j<6000;j++){
Person p = new Person();
p.age = j;
p.gender = "gender"+j;
p.name = "name"+j;
l.add(p);
}
}
原始数据结构 压缩前json数据长度 ---->273011 //由于i和j变更,数据会略有变化
变种数据结构 压缩前json数据长度 ---->129032 //由于i和j变更,数据会略有变化
i=x; j=y;
//x=1,j=6000:表明数据没有任何重复的情形
x=1; j=6000;
原始数据结构 Gzip压缩后json数据长度 ---->44215
变种数据结构 Gzip压缩后json数据长度 ---->39561
压缩后 原始结构长度:变种数据结构=1.1176411
//x=2,j=3000:表明每一个对象都存在另1个属性彻底一致的对象.单个对象重复率100%
x=2; j=3000;
原始数据结构 Gzip压缩后json数据长度 ---->44204
变种数据结构 Gzip压缩后json数据长度 ---->27628
压缩后 原始结构长度:变种数据结构=1.599971
//余下的表明每单个对象重复率超过100%的状况
x=3; j=2000;
原始数据结构 Gzip压缩后json数据长度 ---->43733
变种数据结构 Gzip压缩后json数据长度 ---->17020
压缩后 原始结构长度:变种数据结构=2.5695064
x=4; j=1500;
原始数据结构 Gzip压缩后json数据长度 ---->43398
变种数据结构 Gzip压缩后json数据长度 ---->13914
压缩后 原始结构长度:变种数据结构=3.119017
x=6; j=1000;
原始数据结构 Gzip压缩后json数据长度 ---->42166
变种数据结构 Gzip压缩后json数据长度 ---->8016
压缩后 原始结构长度:变种数据结构=5.2602296
x=7; j=857;
原始数据结构 Gzip压缩后json数据长度 ---->41743
变种数据结构 Gzip压缩后json数据长度 ---->7024
压缩后 原始结构长度:变种数据结构=5.94291
x=8; j=750;
原始数据结构 Gzip压缩后json数据长度 ---->41561
变种数据结构 Gzip压缩后json数据长度 ---->6378
压缩后 原始结构长度:变种数据结构=6.516306
x=9; j=667;
原始数据结构 Gzip压缩后json数据长度 ---->41491
变种数据结构 Gzip压缩后json数据长度 ---->5870
压缩后 原始结构长度:变种数据结构=7.0683136
x=10; j=600;
原始数据结构 Gzip压缩后json数据长度 ---->7552
变种数据结构 Gzip压缩后json数据长度 ---->5503
压缩后 原始结构长度:变种数据结构=1.3723423
x=12; j=500;
原始数据结构 Gzip压缩后json数据长度 ---->6955
变种数据结构 Gzip压缩后json数据长度 ---->4962
压缩后 原始结构长度:变种数据结构=1.4016526
x=15; j=400;
原始数据结构 Gzip压缩后json数据长度 ---->6207
变种数据结构 Gzip压缩后json数据长度 ---->4179
压缩后 原始结构长度:变种数据结构=1.4852836
x=20; j=300;
原始数据结构 Gzip压缩后json数据长度 ---->5117
变种数据结构 Gzip压缩后json数据长度 ---->3576
压缩后 原始结构长度:变种数据结构=1.4309285
x=30; j=200;
原始数据结构 Gzip压缩后json数据长度 ---->4511
变种数据结构 Gzip压缩后json数据长度 ---->3156
压缩后 原始结构长度:变种数据结构=1.429341
x=40; j=150;
原始数据结构 Gzip压缩后json数据长度 ---->4359
变种数据结构 Gzip压缩后json数据长度 ---->3035
压缩后 原始结构长度:变种数据结构=1.4362438
x=60; j=100;
原始数据结构 Gzip压缩后json数据长度 ---->2832
变种数据结构 Gzip压缩后json数据长度 ---->1382
压缩后 原始结构长度:变种数据结构=2.049204
x=80; j=75;
原始数据结构 Gzip压缩后json数据长度 ---->2581
变种数据结构 Gzip压缩后json数据长度 ---->1217
压缩后 原始结构长度:变种数据结构=2.1207888
x=150; j=40;
原始数据结构 Gzip压缩后json数据长度 ---->1835
变种数据结构 Gzip压缩后json数据长度 ---->890
压缩后 原始结构长度:变种数据结构=2.0617979
x=200; j=30;
原始数据结构 Gzip压缩后json数据长度 ---->1744
变种数据结构 Gzip压缩后json数据长度 ---->797
压缩后 原始结构长度:变种数据结构=2.1882057
x=300; j=20;
原始数据结构 Gzip压缩后json数据长度 ---->1539
变种数据结构 Gzip压缩后json数据长度 ---->739
压缩后 原始结构长度:变种数据结构=2.082544
x=316; j=19;
原始数据结构 Gzip压缩后json数据长度 ---->1269
变种数据结构 Gzip压缩后json数据长度 ---->725
压缩后 原始结构长度:变种数据结构=1.7503449
x=400; j=15;
原始数据结构 Gzip压缩后json数据长度 ---->1488
变种数据结构 Gzip压缩后json数据长度 ---->662
压缩后 原始结构长度:变种数据结构=2.247734
x=500; j=12;
原始数据结构 Gzip压缩后json数据长度 ---->1453
变种数据结构 Gzip压缩后json数据长度 ---->563
压缩后 原始结构长度:变种数据结构=2.580817
x=600; j=10;
原始数据结构 Gzip压缩后json数据长度 ---->1044
变种数据结构 Gzip压缩后json数据长度 ---->573
压缩后 原始结构长度:变种数据结构=1.8219895
x=667; j=9;
原始数据结构 Gzip压缩后json数据长度 ---->1291
变种数据结构 Gzip压缩后json数据长度 ---->527
压缩后 原始结构长度:变种数据结构=2.4497154
x=750; j=8;
原始数据结构 Gzip压缩后json数据长度 ---->1155
变种数据结构 Gzip压缩后json数据长度 ---->520
压缩后 原始结构长度:变种数据结构=2.2211537
x=1000; j=6;
原始数据结构 Gzip压缩后json数据长度 ---->1269
变种数据结构 Gzip压缩后json数据长度 ---->429
压缩后 原始结构长度:变种数据结构=2.958042
x=1200; j=5;
原始数据结构 Gzip压缩后json数据长度 ---->1135
变种数据结构 Gzip压缩后json数据长度 ---->478
压缩后 原始结构长度:变种数据结构=2.374477
x=3000; j=2;
原始数据结构 Gzip压缩后json数据长度 ---->990
变种数据结构 Gzip压缩后json数据长度 ---->382
压缩后 原始结构长度:变种数据结构=2.591623
x=6000; j=1;
原始数据结构 Gzip压缩后json数据长度 ---->590
变种数据结构 Gzip压缩后json数据长度 ---->311
压缩后 原始结构长度:变种数据结构=1.897106
当每一个对象属性重复率低于100%的状况下打印结果:
===================================================
原始数据结构 压缩前json数据长度 ---->314681
变种数据结构 压缩前json数据长度 ---->170702
原始数据结构 Gzip压缩后json数据长度 ---->44215
变种数据结构 Gzip压缩后json数据长度 ---->39561
重复率为 0.0 压缩后:原始结构长度:变种数据结构=1.1176411
===================================================
原始数据结构 压缩前json数据长度 ---->629141
变种数据结构 压缩前json数据长度 ---->341162
原始数据结构 Gzip压缩后json数据长度 ---->88279
变种数据结构 Gzip压缩后json数据长度 ---->66875
重复率为 0.0050251256 压缩后:原始结构长度:变种数据结构=1.3200598
===================================================
原始数据结构 压缩前json数据长度 ---->943421
变种数据结构 压缩前json数据长度 ---->511442
原始数据结构 Gzip压缩后json数据长度 ---->131892
变种数据结构 Gzip压缩后json数据长度 ---->90806
重复率为 0.01010101 压缩后:原始结构长度:变种数据结构=1.4524591
===================================================
原始数据结构 压缩前json数据长度 ---->1257521
变种数据结构 压缩前json数据长度 ---->681542
原始数据结构 Gzip压缩后json数据长度 ---->175554
变种数据结构 Gzip压缩后json数据长度 ---->116973
重复率为 0.015228426 压缩后:原始结构长度:变种数据结构=1.5008079
===================================================
原始数据结构 压缩前json数据长度 ---->1571501
变种数据结构 压缩前json数据长度 ---->851522
原始数据结构 Gzip压缩后json数据长度 ---->218945
变种数据结构 Gzip压缩后json数据长度 ---->142129
重复率为 0.020408163 压缩后:原始结构长度:变种数据结构=1.5404668
===================================================
原始数据结构 压缩前json数据长度 ---->1885341
变种数据结构 压缩前json数据长度 ---->1021386
原始数据结构 Gzip压缩后json数据长度 ---->262306
变种数据结构 Gzip压缩后json数据长度 ---->168725
重复率为 0.025641024 压缩后:原始结构长度:变种数据结构=1.5546362
===================================================
原始数据结构 压缩前json数据长度 ---->2199091
变种数据结构 压缩前json数据长度 ---->1191160
原始数据结构 Gzip压缩后json数据长度 ---->305678
变种数据结构 Gzip压缩后json数据长度 ---->191222
重复率为 0.030927831 压缩后:原始结构长度:变种数据结构=1.5985503
===================================================
原始数据结构 压缩前json数据长度 ---->2512751
变种数据结构 压缩前json数据长度 ---->1360844
原始数据结构 Gzip压缩后json数据长度 ---->348774
变种数据结构 Gzip压缩后json数据长度 ---->219050
重复率为 0.036269426 压缩后:原始结构长度:变种数据结构=1.5922118
===================================================
原始数据结构 压缩前json数据长度 ---->2826321
变种数据结构 压缩前json数据长度 ---->1530438
原始数据结构 Gzip压缩后json数据长度 ---->391506
变种数据结构 Gzip压缩后json数据长度 ---->243066
重复率为 0.041666664 压缩后:原始结构长度:变种数据结构=1.6106983
===================================================
原始数据结构 压缩前json数据长度 ---->3139801
变种数据结构 压缩前json数据长度 ---->1699942
原始数据结构 Gzip压缩后json数据长度 ---->434274
变种数据结构 Gzip压缩后json数据长度 ---->268432
重复率为 0.047120415 压缩后:原始结构长度:变种数据结构=1.6178175
===================================================
原始数据结构 压缩前json数据长度 ---->3453191
变种数据结构 压缩前json数据长度 ---->1869356
原始数据结构 Gzip压缩后json数据长度 ---->476356
变种数据结构 Gzip压缩后json数据长度 ---->291550
重复率为 0.052631572 压缩后:原始结构长度:变种数据结构=1.6338742
===================================================
原始数据结构 压缩前json数据长度 ---->3766491
变种数据结构 压缩前json数据长度 ---->2038680
原始数据结构 Gzip压缩后json数据长度 ---->518371
变种数据结构 Gzip压缩后json数据长度 ---->317122
重复率为 0.058201052 压缩后:原始结构长度:变种数据结构=1.6346107
===================================================
原始数据结构 压缩前json数据长度 ---->4079701
变种数据结构 压缩前json数据长度 ---->2207914
原始数据结构 Gzip压缩后json数据长度 ---->560526
变种数据结构 Gzip压缩后json数据长度 ---->344023
重复率为 0.06382978 压缩后:原始结构长度:变种数据结构=1.629327
===================================================
原始数据结构 压缩前json数据长度 ---->4392821
变种数据结构 压缩前json数据长度 ---->2377058
原始数据结构 Gzip压缩后json数据长度 ---->602208
变种数据结构 Gzip压缩后json数据长度 ---->365983
重复率为 0.06951871 压缩后:原始结构长度:变种数据结构=1.6454535
===================================================
原始数据结构 压缩前json数据长度 ---->4705851
变种数据结构 压缩前json数据长度 ---->2546112
原始数据结构 Gzip压缩后json数据长度 ---->643532
变种数据结构 Gzip压缩后json数据长度 ---->391465
重复率为 0.07526881 压缩后:原始结构长度:变种数据结构=1.6439068
===================================================
原始数据结构 压缩前json数据长度 ---->5018791
变种数据结构 压缩前json数据长度 ---->2715076
原始数据结构 Gzip压缩后json数据长度 ---->684775
变种数据结构 Gzip压缩后json数据长度 ---->415902
重复率为 0.08108108 压缩后:原始结构长度:变种数据结构=1.6464816
===================================================
原始数据结构 压缩前json数据长度 ---->5331691
变种数据结构 压缩前json数据长度 ---->2883976
原始数据结构 Gzip压缩后json数据长度 ---->725952
变种数据结构 Gzip压缩后json数据长度 ---->438987
重复率为 0.086956516 压缩后:原始结构长度:变种数据结构=1.6536982
===================================================
原始数据结构 压缩前json数据长度 ---->5644501
变种数据结构 压缩前json数据长度 ---->3052786
原始数据结构 Gzip压缩后json数据长度 ---->767578
变种数据结构 Gzip压缩后json数据长度 ---->464169
重复率为 0.09289617 压缩后:原始结构长度:变种数据结构=1.6536607
===================================================
原始数据结构 压缩前json数据长度 ---->5957221
变种数据结构 压缩前json数据长度 ---->3221506
原始数据结构 Gzip压缩后json数据长度 ---->808616
变种数据结构 Gzip压缩后json数据长度 ---->488167
重复率为 0.09890111 压缩后:原始结构长度:变种数据结构=1.6564331
===================================================
原始数据结构 压缩前json数据长度 ---->6269851
变种数据结构 压缩前json数据长度 ---->3390136
原始数据结构 Gzip压缩后json数据长度 ---->848776
变种数据结构 Gzip压缩后json数据长度 ---->511159
重复率为 0.104972385 压缩后:原始结构长度:变种数据结构=1.6604931
===================================================
原始数据结构 压缩前json数据长度 ---->6582391
变种数据结构 压缩前json数据长度 ---->3558676
原始数据结构 Gzip压缩后json数据长度 ---->889184
变种数据结构 Gzip压缩后json数据长度 ---->536695
重复率为 0.11111113 压缩后:原始结构长度:变种数据结构=1.6567771
===================================================
原始数据结构 压缩前json数据长度 ---->6894841
变种数据结构 压缩前json数据长度 ---->3727126
原始数据结构 Gzip压缩后json数据长度 ---->928982
变种数据结构 Gzip压缩后json数据长度 ---->557274
重复率为 0.11731845 压缩后:原始结构长度:变种数据结构=1.6670111
===================================================
原始数据结构 压缩前json数据长度 ---->7207201
变种数据结构 压缩前json数据长度 ---->3895486
原始数据结构 Gzip压缩后json数据长度 ---->968845
变种数据结构 Gzip压缩后json数据长度 ---->583064
重复率为 0.12359552 压缩后:原始结构长度:变种数据结构=1.6616443
===================================================
原始数据结构 压缩前json数据长度 ---->7519471
变种数据结构 压缩前json数据长度 ---->4063756
原始数据结构 Gzip压缩后json数据长度 ---->1013093
变种数据结构 Gzip压缩后json数据长度 ---->606056
重复率为 0.12994352 压缩后:原始结构长度:变种数据结构=1.6716162
===================================================
原始数据结构 压缩前json数据长度 ---->7831651
变种数据结构 压缩前json数据长度 ---->4231936
原始数据结构 Gzip压缩后json数据长度 ---->1057283
变种数据结构 Gzip压缩后json数据长度 ---->626963
重复率为 0.13636366 压缩后:原始结构长度:变种数据结构=1.6863563
===================================================
原始数据结构 压缩前json数据长度 ---->8143741
变种数据结构 压缩前json数据长度 ---->4400026
原始数据结构 Gzip压缩后json数据长度 ---->1101480
变种数据结构 Gzip压缩后json数据长度 ---->650165
重复率为 0.14285716 压缩后:原始结构长度:变种数据结构=1.6941546
===================================================
原始数据结构 压缩前json数据长度 ---->8455741
变种数据结构 压缩前json数据长度 ---->4568026
原始数据结构 Gzip压缩后json数据长度 ---->1145324
变种数据结构 Gzip压缩后json数据长度 ---->675800
重复率为 0.1494253 压缩后:原始结构长度:变种数据结构=1.6947677
===================================================
原始数据结构 压缩前json数据长度 ---->8767651
变种数据结构 压缩前json数据长度 ---->4735936
原始数据结构 Gzip压缩后json数据长度 ---->1189441
变种数据结构 Gzip压缩后json数据长度 ---->696474
重复率为 0.15606937 压缩后:原始结构长度:变种数据结构=1.7078038
===================================================
原始数据结构 压缩前json数据长度 ---->9079471
变种数据结构 压缩前json数据长度 ---->4903756
原始数据结构 Gzip压缩后json数据长度 ---->1233352
变种数据结构 Gzip压缩后json数据长度 ---->720694
重复率为 0.1627907 压缩后:原始结构长度:变种数据结构=1.7113394
===================================================
原始数据结构 压缩前json数据长度 ---->9391201
变种数据结构 压缩前json数据长度 ---->5071486
原始数据结构 Gzip压缩后json数据长度 ---->1277550
变种数据结构 Gzip压缩后json数据长度 ---->741108
重复率为 0.16959064 压缩后:原始结构长度:变种数据结构=1.7238379
===================================================
原始数据结构 压缩前json数据长度 ---->9702791
变种数据结构 压缩前json数据长度 ---->5239100
原始数据结构 Gzip压缩后json数据长度 ---->1321359
变种数据结构 Gzip压缩后json数据长度 ---->763320
重复率为 0.17647058 压缩后:原始结构长度:变种数据结构=1.7310683
===================================================
原始数据结构 压缩前json数据长度 ---->10014291
变种数据结构 压缩前json数据长度 ---->5406624
原始数据结构 Gzip压缩后json数据长度 ---->1365756
变种数据结构 Gzip压缩后json数据长度 ---->782468
重复率为 0.18343192 压缩后:原始结构长度:变种数据结构=1.7454464
===================================================
原始数据结构 压缩前json数据长度 ---->10325701
变种数据结构 压缩前json数据长度 ---->5574058
原始数据结构 Gzip压缩后json数据长度 ---->1409791
变种数据结构 Gzip压缩后json数据长度 ---->809521
重复率为 0.19047616 压缩后:原始结构长度:变种数据结构=1.7415125
===================================================
原始数据结构 压缩前json数据长度 ---->10637021
变种数据结构 压缩前json数据长度 ---->5741402
原始数据结构 Gzip压缩后json数据长度 ---->1453682
变种数据结构 Gzip压缩后json数据长度 ---->828981
重复率为 0.19760476 压缩后:原始结构长度:变种数据结构=1.753577
===================================================
原始数据结构 压缩前json数据长度 ---->10948308
变种数据结构 压缩前json数据长度 ---->5908713
原始数据结构 Gzip压缩后json数据长度 ---->1497843
变种数据结构 Gzip压缩后json数据长度 ---->852966
重复率为 0.20481923 压缩后:原始结构长度:变种数据结构=1.7560407
===================================================
原始数据结构 压缩前json数据长度 ---->11259595
变种数据结构 压缩前json数据长度 ---->6076024
原始数据结构 Gzip压缩后json数据长度 ---->1542039
变种数据结构 Gzip压缩后json数据长度 ---->872647
重复率为 0.21212116 压缩后:原始结构长度:变种数据结构=1.7670822
===================================================
原始数据结构 压缩前json数据长度 ---->11570882
变种数据结构 压缩前json数据长度 ---->6243335
原始数据结构 Gzip压缩后json数据长度 ---->1585781
变种数据结构 Gzip压缩后json数据长度 ---->891023
重复率为 0.21951213 压缩后:原始结构长度:变种数据结构=1.7797307
===================================================
原始数据结构 压缩前json数据长度 ---->11882169
变种数据结构 压缩前json数据长度 ---->6410646
原始数据结构 Gzip压缩后json数据长度 ---->1629443
变种数据结构 Gzip压缩后json数据长度 ---->915561
重复率为 0.2269938 压缩后:原始结构长度:变种数据结构=1.7797209
===================================================
原始数据结构 压缩前json数据长度 ---->12193456
变种数据结构 压缩前json数据长度 ---->6577957
原始数据结构 Gzip压缩后json数据长度 ---->1673135
变种数据结构 Gzip压缩后json数据长度 ---->937219
重复率为 0.23456782 压缩后:原始结构长度:变种数据结构=1.7852124
===================================================
原始数据结构 压缩前json数据长度 ---->12504743
变种数据结构 压缩前json数据长度 ---->6745268
原始数据结构 Gzip压缩后json数据长度 ---->1717525
变种数据结构 Gzip压缩后json数据长度 ---->956429
重复率为 0.24223594 压缩后:原始结构长度:变种数据结构=1.7957684
===================================================
原始数据结构 压缩前json数据长度 ---->12816030
变种数据结构 压缩前json数据长度 ---->6912579
原始数据结构 Gzip压缩后json数据长度 ---->1761849
变种数据结构 Gzip压缩后json数据长度 ---->976092
重复率为 0.24999991 压缩后:原始结构长度:变种数据结构=1.805003
===================================================
原始数据结构 压缩前json数据长度 ---->13127317
变种数据结构 压缩前json数据长度 ---->7079890
原始数据结构 Gzip压缩后json数据长度 ---->1806001
变种数据结构 Gzip压缩后json数据长度 ---->995442
重复率为 0.25786152 压缩后:原始结构长度:变种数据结构=1.8142705
===================================================
原始数据结构 压缩前json数据长度 ---->13438604
变种数据结构 压缩前json数据长度 ---->7247201
原始数据结构 Gzip压缩后json数据长度 ---->1850241
变种数据结构 Gzip压缩后json数据长度 ---->1014463
重复率为 0.26582268 压缩后:原始结构长度:变种数据结构=1.8238624
===================================================
原始数据结构 压缩前json数据长度 ---->13749891
变种数据结构 压缩前json数据长度 ---->7414512
原始数据结构 Gzip压缩后json数据长度 ---->1893946
变种数据结构 Gzip压缩后json数据长度 ---->1038690
重复率为 0.27388522 压缩后:原始结构长度:变种数据结构=1.8233987
===================================================
原始数据结构 压缩前json数据长度 ---->14061178
变种数据结构 压缩前json数据长度 ---->7581823
原始数据结构 Gzip压缩后json数据长度 ---->1938584
变种数据结构 Gzip压缩后json数据长度 ---->1064229
重复率为 0.28205115 压缩后:原始结构长度:变种数据结构=1.8215854
===================================================
原始数据结构 压缩前json数据长度 ---->14372465
变种数据结构 压缩前json数据长度 ---->7749134
原始数据结构 Gzip压缩后json数据长度 ---->1982416
变种数据结构 Gzip压缩后json数据长度 ---->1079948
重复率为 0.29032245 压缩后:原始结构长度:变种数据结构=1.8356588
===================================================
原始数据结构 压缩前json数据长度 ---->14683752
变种数据结构 压缩前json数据长度 ---->7916445
原始数据结构 Gzip压缩后json数据长度 ---->2026663
变种数据结构 Gzip压缩后json数据长度 ---->1102001
重复率为 0.29870114 压缩后:原始结构长度:变种数据结构=1.8390754
===================================================
原始数据结构 压缩前json数据长度 ---->14995039
变种数据结构 压缩前json数据长度 ---->8083756
原始数据结构 Gzip压缩后json数据长度 ---->2070714
变种数据结构 Gzip压缩后json数据长度 ---->1125712
重复率为 0.30718938 压缩后:原始结构长度:变种数据结构=1.8394705
===================================================
原始数据结构 压缩前json数据长度 ---->15306326
变种数据结构 压缩前json数据长度 ---->8251067
原始数据结构 Gzip压缩后json数据长度 ---->2114297
变种数据结构 Gzip压缩后json数据长度 ---->1145723
重复率为 0.3157893 压缩后:原始结构长度:变种数据结构=1.8453823
===================================================
原始数据结构 压缩前json数据长度 ---->15617613
变种数据结构 压缩前json数据长度 ---->8418378
原始数据结构 Gzip压缩后json数据长度 ---->2158166
变种数据结构 Gzip压缩后json数据长度 ---->1164141
重复率为 0.32450312 压缩后:原始结构长度:变种数据结构=1.8538699
===================================================
原始数据结构 压缩前json数据长度 ---->15928900
变种数据结构 压缩前json数据长度 ---->8585689
原始数据结构 Gzip压缩后json数据长度 ---->2201712
变种数据结构 Gzip压缩后json数据长度 ---->1189557
重复率为 0.33333313 压缩后:原始结构长度:变种数据结构=1.8508672
===================================================
原始数据结构 压缩前json数据长度 ---->16240187
变种数据结构 压缩前json数据长度 ---->8753000
原始数据结构 Gzip压缩后json数据长度 ---->2245653
变种数据结构 Gzip压缩后json数据长度 ---->1207825
重复率为 0.3422817 压缩后:原始结构长度:变种数据结构=1.8592536
===================================================
原始数据结构 压缩前json数据长度 ---->16551474
变种数据结构 压缩前json数据长度 ---->8920311
原始数据结构 Gzip压缩后json数据长度 ---->2289778
变种数据结构 Gzip压缩后json数据长度 ---->1228716
重复率为 0.35135114 压缩后:原始结构长度:变种数据结构=1.8635535
===================================================
原始数据结构 压缩前json数据长度 ---->16862761
变种数据结构 压缩前json数据长度 ---->9087622
原始数据结构 Gzip压缩后json数据长度 ---->2333883
变种数据结构 Gzip压缩后json数据长度 ---->1248197
重复率为 0.36054403 压缩后:原始结构长度:变种数据结构=1.8698034
===================================================
原始数据结构 压缩前json数据长度 ---->17174048
变种数据结构 压缩前json数据长度 ---->9254933
原始数据结构 Gzip压缩后json数据长度 ---->2377734
变种数据结构 Gzip压缩后json数据长度 ---->1263293
重复率为 0.3698628 压缩后:原始结构长度:变种数据结构=1.8821714
===================================================
原始数据结构 压缩前json数据长度 ---->17485335
变种数据结构 压缩前json数据长度 ---->9422244
原始数据结构 Gzip压缩后json数据长度 ---->2421204
变种数据结构 Gzip压缩后json数据长度 ---->1286647
重复率为 0.3793101 压缩后:原始结构长度:变种数据结构=1.8817935
===================================================
原始数据结构 压缩前json数据长度 ---->17796622
变种数据结构 压缩前json数据长度 ---->9589555
原始数据结构 Gzip压缩后json数据长度 ---->2464871
变种数据结构 Gzip压缩后json数据长度 ---->1307479
重复率为 0.38888866 压缩后:原始结构长度:变种数据结构=1.8852088
===================================================
原始数据结构 压缩前json数据长度 ---->18107909
变种数据结构 压缩前json数据长度 ---->9756866
原始数据结构 Gzip压缩后json数据长度 ---->2508873
变种数据结构 Gzip压缩后json数据长度 ---->1327997
重复率为 0.39860114 压缩后:原始结构长度:变种数据结构=1.8892158
===================================================
原始数据结构 压缩前json数据长度 ---->18419196
变种数据结构 压缩前json数据长度 ---->9924177
原始数据结构 Gzip压缩后json数据长度 ---->2552954
变种数据结构 Gzip压缩后json数据长度 ---->1342020
重复率为 0.40845042 压缩后:原始结构长度:变种数据结构=1.9023218
===================================================
原始数据结构 压缩前json数据长度 ---->18730483
变种数据结构 压缩前json数据长度 ---->10091488
原始数据结构 Gzip压缩后json数据长度 ---->2596616
变种数据结构 Gzip压缩后json数据长度 ---->1369092
重复率为 0.41843942 压缩后:原始结构长度:变种数据结构=1.8965971
===================================================
原始数据结构 压缩前json数据长度 ---->19041770
变种数据结构 压缩前json数据长度 ---->10258799
原始数据结构 Gzip压缩后json数据长度 ---->2640984
变种数据结构 Gzip压缩后json数据长度 ---->1383626
重复率为 0.42857113 压缩后:原始结构长度:变种数据结构=1.9087412
===================================================
原始数据结构 压缩前json数据长度 ---->19353057
变种数据结构 压缩前json数据长度 ---->10426110
原始数据结构 Gzip压缩后json数据长度 ---->2685199
变种数据结构 Gzip压缩后json数据长度 ---->1402782
重复率为 0.4388486 压缩后:原始结构长度:变种数据结构=1.9141955
===================================================
原始数据结构 压缩前json数据长度 ---->19664344
变种数据结构 压缩前json数据长度 ---->10593421
原始数据结构 Gzip压缩后json数据长度 ---->2729710
变种数据结构 Gzip压缩后json数据长度 ---->1418750
重复率为 0.44927505 压缩后:原始结构长度:变种数据结构=1.9240247
===================================================
原始数据结构 压缩前json数据长度 ---->19975631
变种数据结构 压缩前json数据长度 ---->10760732
原始数据结构 Gzip压缩后json数据长度 ---->2773735
变种数据结构 Gzip压缩后json数据长度 ---->1435122
重复率为 0.45985368 压缩后:原始结构长度:变种数据结构=1.932752
===================================================
原始数据结构 压缩前json数据长度 ---->20286918
变种数据结构 压缩前json数据长度 ---->10928043
原始数据结构 Gzip压缩后json数据长度 ---->2818175
变种数据结构 Gzip压缩后json数据长度 ---->1458645
重复率为 0.47058788 压缩后:原始结构长度:变种数据结构=1.93205
===================================================
原始数据结构 压缩前json数据长度 ---->20598205
变种数据结构 压缩前json数据长度 ---->11095354
原始数据结构 Gzip压缩后json数据长度 ---->2862715
变种数据结构 Gzip压缩后json数据长度 ---->1473688
重复率为 0.4814811 压缩后:原始结构长度:变种数据结构=1.9425516
===================================================
原始数据结构 压缩前json数据长度 ---->20909492
变种数据结构 压缩前json数据长度 ---->11262665
原始数据结构 Gzip压缩后json数据长度 ---->2906140
变种数据结构 Gzip压缩后json数据长度 ---->1497577
重复率为 0.49253693 压缩后:原始结构长度:变种数据结构=1.9405613
===================================================
原始数据结构 压缩前json数据长度 ---->21220779
变种数据结构 压缩前json数据长度 ---->11429976
原始数据结构 Gzip压缩后json数据长度 ---->2951053
变种数据结构 Gzip压缩后json数据长度 ---->1513485
重复率为 0.50375897 压缩后:原始结构长度:变种数据结构=1.9498396
===================================================
原始数据结构 压缩前json数据长度 ---->21532066
变种数据结构 压缩前json数据长度 ---->11597287
原始数据结构 Gzip压缩后json数据长度 ---->2995263
变种数据结构 Gzip压缩后json数据长度 ---->1528176
重复率为 0.5151511 压缩后:原始结构长度:变种数据结构=1.9600248
===================================================
原始数据结构 压缩前json数据长度 ---->21843353
变种数据结构 压缩前json数据长度 ---->11764598
原始数据结构 Gzip压缩后json数据长度 ---->3039623
变种数据结构 Gzip压缩后json数据长度 ---->1546990
重复率为 0.5267171 压缩后:原始结构长度:变种数据结构=1.9648627
===================================================
原始数据结构 压缩前json数据长度 ---->22154640
变种数据结构 压缩前json数据长度 ---->11931909
原始数据结构 Gzip压缩后json数据长度 ---->3083971
变种数据结构 Gzip压缩后json数据长度 ---->1563906
重复率为 0.5384611 压缩后:原始结构长度:变种数据结构=1.971967
===================================================
原始数据结构 压缩前json数据长度 ---->22465927
变种数据结构 压缩前json数据长度 ---->12099220
原始数据结构 Gzip压缩后json数据长度 ---->3128112
变种数据结构 Gzip压缩后json数据长度 ---->1580792
重复率为 0.55038714 压缩后:原始结构长度:变种数据结构=1.9788258
===================================================
原始数据结构 压缩前json数据长度 ---->22777214
变种数据结构 压缩前json数据长度 ---->12266531
原始数据结构 Gzip压缩后json数据长度 ---->3171693
变种数据结构 Gzip压缩后json数据长度 ---->1600344
重复率为 0.5624995 压缩后:原始结构长度:变种数据结构=1.981882
===================================================
原始数据结构 压缩前json数据长度 ---->23088501
变种数据结构 压缩前json数据长度 ---->12433842
原始数据结构 Gzip压缩后json数据长度 ---->3215617
变种数据结构 Gzip压缩后json数据长度 ---->1618740
重复率为 0.57480264 压缩后:原始结构长度:变种数据结构=1.9864938
===================================================
原始数据结构 压缩前json数据长度 ---->23399788
变种数据结构 压缩前json数据长度 ---->12601153
原始数据结构 Gzip压缩后json数据长度 ---->3259832
变种数据结构 Gzip压缩后json数据长度 ---->1637726
重复率为 0.5873011 压缩后:原始结构长度:变种数据结构=1.9904624
===================================================
原始数据结构 压缩前json数据长度 ---->23711075
变种数据结构 压缩前json数据长度 ---->12768464
原始数据结构 Gzip压缩后json数据长度 ---->3304008
变种数据结构 Gzip压缩后json数据长度 ---->1652686
重复率为 0.5999994 压缩后:原始结构长度:变种数据结构=1.9991747
===================================================
原始数据结构 压缩前json数据长度 ---->24022362
变种数据结构 压缩前json数据长度 ---->12935775
原始数据结构 Gzip压缩后json数据长度 ---->3347657
变种数据结构 Gzip压缩后json数据长度 ---->1670445
重复率为 0.61290264 压缩后:原始结构长度:变种数据结构=2.004051
===================================================
原始数据结构 压缩前json数据长度 ---->24333649
变种数据结构 压缩前json数据长度 ---->13103086
原始数据结构 Gzip压缩后json数据长度 ---->3391716
变种数据结构 Gzip压缩后json数据长度 ---->1683890
重复率为 0.62601566 压缩后:原始结构长度:变种数据结构=2.0142148
===================================================
原始数据结构 压缩前json数据长度 ---->24644936
变种数据结构 压缩前json数据长度 ---->13270397
原始数据结构 Gzip压缩后json数据长度 ---->3436086
变种数据结构 Gzip压缩后json数据长度 ---->1704452
重复率为 0.6393436 压缩后:原始结构长度:变种数据结构=2.0159476
===================================================
原始数据结构 压缩前json数据长度 ---->24956223
变种数据结构 压缩前json数据长度 ---->13437708
原始数据结构 Gzip压缩后json数据长度 ---->3480064
变种数据结构 Gzip压缩后json数据长度 ---->1719727
重复率为 0.65289193 压缩后:原始结构长度:变种数据结构=2.0236142
===================================================
原始数据结构 压缩前json数据长度 ---->25267510
变种数据结构 压缩前json数据长度 ---->13605019
原始数据结构 Gzip压缩后json数据长度 ---->3524494
变种数据结构 Gzip压缩后json数据长度 ---->1735590
重复率为 0.666666 压缩后:原始结构长度:变种数据结构=2.030718
===================================================
原始数据结构 压缩前json数据长度 ---->25578797
变种数据结构 压缩前json数据长度 ---->13772330
原始数据结构 Gzip压缩后json数据长度 ---->3569109
变种数据结构 Gzip压缩后json数据长度 ---->1757409
重复率为 0.6806716 压缩后:原始结构长度:变种数据结构=2.0308926
===================================================
原始数据结构 压缩前json数据长度 ---->25890084
变种数据结构 压缩前json数据长度 ---->13939641
原始数据结构 Gzip压缩后json数据长度 ---->3613919
变种数据结构 Gzip压缩后json数据长度 ---->1770126
重复率为 0.6949145 压缩后:原始结构长度:变种数据结构=2.041617
===================================================
原始数据结构 压缩前json数据长度 ---->26201371
变种数据结构 压缩前json数据长度 ---->14106952
原始数据结构 Gzip压缩后json数据长度 ---->3658034
变种数据结构 Gzip压缩后json数据长度 ---->1787002
重复率为 0.70940095 压缩后:原始结构长度:变种数据结构=2.0470228
===================================================
原始数据结构 压缩前json数据长度 ---->26512658
变种数据结构 压缩前json数据长度 ---->14274263
原始数据结构 Gzip压缩后json数据长度 ---->3702835
变种数据结构 Gzip压缩后json数据长度 ---->1799515
重复率为 0.7241371 压缩后:原始结构长度:变种数据结构=2.057685
===================================================
原始数据结构 压缩前json数据长度 ---->26823945
变种数据结构 压缩前json数据长度 ---->14441574
原始数据结构 Gzip压缩后json数据长度 ---->3746980
变种数据结构 Gzip压缩后json数据长度 ---->1818417
重复率为 0.7391296 压缩后:原始结构长度:变种数据结构=2.0605724
===================================================
原始数据结构 压缩前json数据长度 ---->27135232
变种数据结构 压缩前json数据长度 ---->14608885
原始数据结构 Gzip压缩后json数据长度 ---->3790555
变种数据结构 Gzip压缩后json数据长度 ---->1836003
重复率为 0.7543851 压缩后:原始结构长度:变种数据结构=2.064569
===================================================
原始数据结构 压缩前json数据长度 ---->27446519
变种数据结构 压缩前json数据长度 ---->14776196
原始数据结构 Gzip压缩后json数据长度 ---->3834464
变种数据结构 Gzip压缩后json数据长度 ---->1851563
重复率为 0.76991063 压缩后:原始结构长度:变种数据结构=2.0709336
===================================================
原始数据结构 压缩前json数据长度 ---->27757806
变种数据结构 压缩前json数据长度 ---->14943507
原始数据结构 Gzip压缩后json数据长度 ---->3879072
变种数据结构 Gzip压缩后json数据长度 ---->1873192
重复率为 0.7857134 压缩后:原始结构长度:变种数据结构=2.0708354
===================================================
原始数据结构 压缩前json数据长度 ---->28069093
变种数据结构 压缩前json数据长度 ---->15110818
原始数据结构 Gzip压缩后json数据长度 ---->3923316
变种数据结构 Gzip压缩后json数据长度 ---->1894024
重复率为 0.80180085 压缩后:原始结构长度:变种数据结构=2.0714183
===================================================
原始数据结构 压缩前json数据长度 ---->28380380
变种数据结构 压缩前json数据长度 ---->15278129
原始数据结构 Gzip压缩后json数据长度 ---->3967482
变种数据结构 Gzip压缩后json数据长度 ---->1916387
重复率为 0.81818086 压缩后:原始结构长度:变种数据结构=2.0702927
===================================================
原始数据结构 压缩前json数据长度 ---->28691667
变种数据结构 压缩前json数据长度 ---->15445440
原始数据结构 Gzip压缩后json数据长度 ---->4011094
变种数据结构 Gzip压缩后json数据长度 ---->1933486
重复率为 0.8348614 压缩后:原始结构长度:变种数据结构=2.07454
===================================================
原始数据结构 压缩前json数据长度 ---->29002954
变种数据结构 压缩前json数据长度 ---->15612751
原始数据结构 Gzip压缩后json数据长度 ---->4055289
变种数据结构 Gzip压缩后json数据长度 ---->1953997
重复率为 0.8518508 压缩后:原始结构长度:变种数据结构=2.0753813
===================================================
原始数据结构 压缩前json数据长度 ---->29314241
变种数据结构 压缩前json数据长度 ---->15780062
原始数据结构 Gzip压缩后json数据长度 ---->4099592
变种数据结构 Gzip压缩后json数据长度 ---->1974066
重复率为 0.8691578 压缩后:原始结构长度:变种数据结构=2.076725
===================================================
原始数据结构 压缩前json数据长度 ---->29625528
变种数据结构 压缩前json数据长度 ---->15947373
原始数据结构 Gzip压缩后json数据长度 ---->4143573
变种数据结构 Gzip压缩后json数据长度 ---->1987771
重复率为 0.88679135 压缩后:原始结构长度:变种数据结构=2.0845323
===================================================
原始数据结构 压缩前json数据长度 ---->29936815
变种数据结构 压缩前json数据长度 ---->16114684
原始数据结构 Gzip压缩后json数据长度 ---->4187707
变种数据结构 Gzip压缩后json数据长度 ---->2014350
重复率为 0.9047608 压缩后:原始结构长度:变种数据结构=2.078937
===================================================
原始数据结构 压缩前json数据长度 ---->30248102
变种数据结构 压缩前json数据长度 ---->16281995
原始数据结构 Gzip压缩后json数据长度 ---->4232504
变种数据结构 Gzip压缩后json数据长度 ---->2034384
重复率为 0.92307574 压缩后:原始结构长度:变种数据结构=2.0804844
===================================================
原始数据结构 压缩前json数据长度 ---->30559389
变种数据结构 压缩前json数据长度 ---->16449306
原始数据结构 Gzip压缩后json数据长度 ---->4277046
变种数据结构 Gzip压缩后json数据长度 ---->2053854
重复率为 0.94174635 压缩后:原始结构长度:变种数据结构=2.082449
===================================================
原始数据结构 压缩前json数据长度 ---->30870676
变种数据结构 压缩前json数据长度 ---->16616617
原始数据结构 Gzip压缩后json数据长度 ---->4321134
变种数据结构 Gzip压缩后json数据长度 ---->2072485
重复率为 0.960783 压缩后:原始结构长度:变种数据结构=2.0850012
===================================================
原始数据结构 压缩前json数据长度 ---->31181963
变种数据结构 压缩前json数据长度 ---->16783928
原始数据结构 Gzip压缩后json数据长度 ---->4365924
变种数据结构 Gzip压缩后json数据长度 ---->2087159
重复率为 0.9801967 压缩后:原始结构长度:变种数据结构=2.0918024
===================================================
原始数据结构 压缩前json数据长度 ---->31493250
变种数据结构 压缩前json数据长度 ---->16951239
原始数据结构 Gzip压缩后json数据长度 ---->4409476
变种数据结构 Gzip压缩后json数据长度 ---->2100664
重复率为 0.9999986 压缩后:原始结构长度:变种数据结构=2.0990868
复制代码
多线程大部份内容源自凯哥的课程,我的以为比优化典范写得清晰得多
线程就是代码线性执行,执行完毕就结束的一条线.UI线程不会结束是由于其初始化完毕后会执行死循环,因此永远不会执行完毕.
如何简单建立新线程:
//1:直接建立Thread,执行其start方法
Thread t1 = new Thread(){
@Override
public void run() {
System.out.println("Thread:run");
}
};
t1.start();
//2:使用Runnable实例做为参数建立Thread,执行start
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Runnable:run");
}
};
Thread t2 = new Thread(runnable);
t2.start();
复制代码
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("runnable:run()");
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.shutdown();
//好比有40张图片要同时处理
//建立包含40个线程的线程池,每一个线程处理一张图片,处理完毕后shutdown
ExecutorService service = Executors.newFixedThreadPool(40);
for(Bitmap item:bitmaps){
//好比runnable就是处理单张图片的
service.execute(runnable);
}
service.shutdown();
复制代码
如何正确建立ThreadPoolExecutor
3.1:ThreadPoolExecutor构造参数
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 复制代码
3.2:当1个任务被放进线程池,ThreadPoolExecutor具体执行策略以下:
3.3:阻塞队列/BlockingQueue workQueue
3.4:RejectedExecutionHandler handler/拒绝策略有4种
1.hreadPoolExecutor.AbortPolicy:丢弃任务,并抛出RejectedExecutionException异常.ThreadPoolExecutor默认就是使用AbortPolicy.
2.ThreadPoolExecutor.DiscardPolicy:丢弃任务,但不会抛出异常.
3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃排在队列头部的任务,不抛出异常,并尝试从新执行任务.
4.ThreadPoolExecutor.CallerRunsPolicy:丢弃任务,但不抛出异常,并将该任务交给调用此ThreadPoolExecutor的线程执行.
synchronized 的本质
volatile
//引用类型的直接赋值操做有效
private volatile User u = U1;
//修改引用类型的属性,则不是原子性的,volatile无效
U1.name = "吊炸天"
//对引用类型的直接赋值是原子性的
u = U2;
private volatile int a = 0;
private int b = 100;
//volatile没法实现++/--的原子性
a++;
复制代码
针对num++这类复合类的操做,可使用java并发包中的原子操做类原子操做类:AtomicInteger AtomicBoolean等来保证其原子性.
public static AtomicInteger num = new AtomicInteger(0);
num.incrementAndGet();//原子性的num++,经过循环CAS方式
复制代码
下面的代码,每次执行最后打印的结果都不一样,即咱们彻底不可预知调用stop时候当前线程执行了百分之多少.
private static void t2(){
Thread t = new Thread(){
@Override
public void run() {
for(int i=0;i<1000000;i++){
System.out.println(""+i);
}
}
};
t.start();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.stop();
}
复制代码
private static void t2(){
Thread t = new Thread(){
@Override
public void run() {
for(int i=0;i<1000000;i++){
//检查线程是否处于中断状态,且检查是否知足指定条件
//若是不知足指定条件,即便处于中断状态也继续执行.
if(isInterrupted()&&i>800000){
//先作收尾工做
//return 结束
return;
}
System.out.println(""+i);
}
}
};
t.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//调用了interrupt后,在run中监查是否已经被打断,若是已经被打断,且知足指定条件,
//就return,线程就执行完了
t.interrupt();
}
......
799999
800000
Process finished with exit code 0
复制代码
private static void t3(){
Thread thread = new Thread(){
@Override
public void run() {
long t1 = System.currentTimeMillis();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
long t2 = System.currentTimeMillis();
System.out.println("老子被叫醒了:睡了"+(t2-t1)+"ms");
//用于作线程收尾工做,而后return
return;
}
System.out.println("AAAAAAAA");
}
};
thread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
老子被叫醒了:睡了493ms
Process finished with exit code 0
复制代码
private String str = null;
private synchronized void setStr(String str){
System.out.println("setStr时间:"+System.currentTimeMillis());
this.str = str;
notifyAll();
}
private synchronized void printStr(){
while (str==null){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程:"+Thread.currentThread().getName()+
" printStr时间:"+System.currentTimeMillis());
System.out.println("str:"+str);
}
private void t4(){
(new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setStr("老子设置一下");
}
}).start();
(new Thread(){
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:"+Thread.currentThread().getName()+
" 尝试printStr时间:"+System.currentTimeMillis());
printStr();
}
}).start();
(new Thread(){
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:"+Thread.currentThread().getName()+
" 尝试printStr时间:"+System.currentTimeMillis());
printStr();
}
}).start();
}
线程:Thread-2 尝试printStr时间:1539247468146
线程:Thread-1 尝试printStr时间:1539247468944
setStr时间:1539247469944
线程:Thread-1 printStr时间:1539247469944
str:老子设置一下
线程:Thread-2 printStr时间:1539247469944
str:老子设置一下
复制代码
讲的太多了这里推荐1个专题RxJava2.x
下面记录一下本身不太熟的几点
styles.xml
<!-- Base application theme. -->
//Activity默认主题
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> //默认主题窗口背景设置为白色 <item name="android:background">@android:color/white</item> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowFullscreen">true</item> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
//入口Activity的theme单独设置
<style name="ThemeSplash" parent="Theme.AppCompat.Light.NoActionBar"> //入口Activity初始窗口背景设置为品牌宣传图片 <item name="android:background">@mipmap/startbg</item> <item name="android:windowNoTitle">true</item> <item name="android:windowFullscreen">true</item> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
AndroidManifest.xml
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:theme="@style/ThemeSplash">//为入口Activity单独指定theme
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</manifest>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
//在代码执行到入口Activity时候设置入口Activity为默认主题
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_all = findViewById(R.id.tv_all);
tv_local = findViewById(R.id.tv_local);
//注册全局广播
registerReceiver(globalReceiver,new IntentFilter("global"));
//注册本地广播
LocalBroadcastManager.getInstance(this).registerReceiver(localBroadReceiver,new IntentFilter("localBroadCast"));
}
}
复制代码
当咱们使用资源id来去引用一张图片时,Android会使用一些规则来去帮咱们匹配最适合的图片。什么叫最适合的图片?好比个人手机屏幕密度是xxhdpi,那么drawable-xxhdpi文件夹下的图片就是最适合的图片。所以,当我引用android_logo这张图时,若是drawable-xxhdpi文件夹下有这张图就会优先被使用,在这种状况下,图片是不会被缩放的。可是,若是drawable-xxhdpi文件夹下没有这张图时, 系统就会自动去其它文件夹下找这张图了,优先会去更高密度的文件夹下找这张图片,咱们当前的场景就是drawable-xxxhdpi文件夹,而后发现这里也没有android_logo这张图,接下来会尝试再找更高密度的文件夹,发现没有更高密度的了,这个时候会去drawable-nodpi文件夹找这张图,发现也没有,那么就会去更低密度的文件夹下面找,依次是drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。 整体匹配规则就是这样,那么好比说如今终于在drawable-mdpi文件夹下面找到android_logo这张图了,可是系统会认为你这张图是专门为低密度的设备所设计的,若是直接将这张图在当前的高密度设备上使用就有可能会出现像素太低的状况,因而系统自动帮咱们作了这样一个放大操做。 那么一样的道理,若是系统是在drawable-xxxhdpi文件夹下面找到这张图的话,它会认为这张图是为更高密度的设备所设计的,若是直接将这张图在当前设备上使用就有可能会出现像素太高的状况,因而会自动帮咱们作一个缩小的操做
好比一张图片O已经存在,若是有View的背景就是O旋转事后的样子,能够直接用O建立RotateDrawable.而后将设置给View使用.
注意:RotateDrawable已经重写了其onLevelChange方法,因此必定要设置level才会生效
@Override
protected boolean onLevelChange(int level) {
super.onLevelChange(level);
final float value = level / (float) MAX_LEVEL;
final float degrees = MathUtils.lerp(mState.mFromDegrees, mState.mToDegrees, value);
mState.mCurrentDegrees = degrees;
invalidateSelf();
return true;
}
复制代码
实例:
1.首先建立xml文件
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/close10" android:fromDegrees="90" android:toDegrees="120" android:pivotX="50%" android:pivotY="50%" >
</rotate>
2.在Java代码中获取该xml对应的Drawable实例,并设置level为10000
Drawable drawable = getResources().getDrawable(R.drawable.rotate_close);
drawable.setLevel(10000);
3.将Drawable设置为View的背景
findViewById(R.id.v).setBackgroundDrawable(drawable);
复制代码
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
复制代码
网络优化主要有几个方面:下降网络请求数量,下降单次请求响应的数据量,在弱网环境下将非必要网络请求延缓至网络环境好的时候.
App优化之网络优化
文章中提到:用户点赞操做, 能够直接给出界面的点同意功的反馈, 使用JobScheduler在网络状况较好的时候打包请求.
JobScheduler在网络优化中出现过,WakeLock涉及电量优化,AlarmManager和WakeLock有类似,但侧重点不一样.
JobScheduler:
Android Jobscheduler使用
Android开发笔记(一百四十三)任务调度JobScheduler
WakeLock:
Android WakeLock详解
Android PowerManager.WakeLock使用小结
Android的PowerManager和PowerManager.WakeLock用法简析
AlarmManager和WakeLock使用:
后台任务 - 保持设备唤醒状态
public class SampleApplication extends Application {
@Override
public void onCreate() {
Debug.startMethodTracing("JetApp");
super.onCreate();
LeakCanary.install(this);
// init logger.
AppLog.init();
// init crash helper
CrashHelper.init(this);
// init Push
PushPlatform.init(this);
// init Feedback
FeedbackPlatform.init(this);
Debug.stopMethodTracing();
}
复制代码
代码执行完毕,会在Android设备中生成JetApp.trace文件.经过Device File Explorer,找到sdcard/Android/data/app包名/files/JetApp.trace下面只看Window.OnFrameMetricsAvailableListener怎么用.
从Android 7.0 (API level 24)开始,Android引入Window.OnFrameMetricsAvailableList接口用于提供每一帧绘制各阶段的耗时,数据源与GPU Profile相同.
public interface OnFrameMetricsAvailableListener {
void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics,int dropCountSinceLastInvocation);
}
/** * 包含1帧的周期内,渲染系统各个方法的耗时数据. */
public final class FrameMetrics {
****
//经过getMetric获取layout/measure耗时所用的id
public static final int LAYOUT_MEASURE_DURATION = 3;
public static final int DRAW_DURATION = 4;
/** * 获取当前帧指定id表明的方法/过程的耗时,单位是纳秒:1纳秒(ns)=10的负6次方毫秒(ms) */
public long getMetric(@Metric int id) {
****
}
}
复制代码
package p1.com.p1;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.FrameMetrics;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.Window.OnFrameMetricsAvailableListener;
import android.widget.Button;
import android.widget.TextView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import kotlin.TypeCastException;
import kotlin.jvm.internal.Intrinsics;
public final class KtMainActivity extends AppCompatActivity {
private final Handler frameMetricsHandler = new Handler();
@RequiresApi(24)
private final OnFrameMetricsAvailableListener frameMetricsAvailableListener = new OnFrameMetricsAvailableListener() {
@Override
public void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCountSinceLastInvocation) {
long costDuration = frameMetrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION);
Log.d("Jet", "layoutMeasureDurationNs: " + costDuration);
}
};
private static final String TAG = "KtMainActivity";
private static final int TOTAL = 100;
private static final int WIDTH = 1920;
private static final int HEIGHT = 1080;
@RequiresApi(3)
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_for_test);
final Button traditionalCalcButton = (Button) this.findViewById(R.id.button_start_calc_traditional);
final Button constraintCalcButton = (Button) this.findViewById(R.id.button_start_calc_constraint);
final TextView textViewFinish = (TextView) this.findViewById(R.id.textview_finish);
traditionalCalcButton.setOnClickListener((OnClickListener) (new OnClickListener() {
public final void onClick(View it) {
Button var10000 = constraintCalcButton;
Intrinsics.checkExpressionValueIsNotNull(constraintCalcButton, "constraintCalcButton");
var10000.setVisibility(View.INVISIBLE);
View var4 = KtMainActivity.this.getLayoutInflater().inflate(R.layout.activity_traditional, (ViewGroup) null);
if (var4 == null) {
throw new TypeCastException("null cannot be cast to non-null type android.view.ViewGroup");
} else {
ViewGroup container = (ViewGroup) var4;
String var10002 = KtMainActivity.this.getString(R.string.executing_nth_iteration);
Intrinsics.checkExpressionValueIsNotNull(var10002, "getString(R.string.executing_nth_iteration)");
KtMainActivity.MeasureLayoutAsyncTask asyncTask = new KtMainActivity.MeasureLayoutAsyncTask(var10002, new WeakReference(traditionalCalcButton), new WeakReference(textViewFinish), new WeakReference(container));
asyncTask.execute(new Void[0]);
}
}
}));
constraintCalcButton.setOnClickListener((OnClickListener) (new OnClickListener() {
public final void onClick(View it) {
Button var10000 = traditionalCalcButton;
Intrinsics.checkExpressionValueIsNotNull(traditionalCalcButton, "traditionalCalcButton");
var10000.setVisibility(View.INVISIBLE);
View var4 = KtMainActivity.this.getLayoutInflater().inflate(R.layout.activity_constraintlayout, (ViewGroup) null);
if (var4 == null) {
throw new TypeCastException("null cannot be cast to non-null type android.view.ViewGroup");
} else {
ViewGroup container = (ViewGroup) var4;
String var10002 = KtMainActivity.this.getString(R.string.executing_nth_iteration);
Intrinsics.checkExpressionValueIsNotNull(var10002, "getString(R.string.executing_nth_iteration)");
KtMainActivity.MeasureLayoutAsyncTask asyncTask = new KtMainActivity.MeasureLayoutAsyncTask(var10002, new WeakReference(constraintCalcButton), new WeakReference(textViewFinish), new WeakReference(container));
asyncTask.execute(new Void[0]);
}
}
}));
}
@RequiresApi(24)
protected void onResume() {
super.onResume();
this.getWindow().addOnFrameMetricsAvailableListener(this.frameMetricsAvailableListener, this.frameMetricsHandler);
}
@RequiresApi(24)
protected void onPause() {
super.onPause();
this.getWindow().removeOnFrameMetricsAvailableListener(this.frameMetricsAvailableListener);
}
@RequiresApi(3)
private static final class MeasureLayoutAsyncTask extends AsyncTask {
@NotNull
private final String executingNthIteration;
@NotNull
private final WeakReference startButtonRef;
@NotNull
private final WeakReference finishTextViewRef;
@NotNull
private final WeakReference containerRef;
@Nullable
protected Void doInBackground(@NotNull Void... voids) {
Intrinsics.checkParameterIsNotNull(voids, "voids");
int i = 0;
for (int var3 = KtMainActivity.TOTAL; i < var3; ++i) {
this.publishProgress(new Integer[]{i});
try {
Thread.sleep(100L);
} catch (InterruptedException var5) {
;
}
}
return null;
}
// $FF: synthetic method
// $FF: bridge method
public Object doInBackground(Object[] var1) {
return this.doInBackground((Void[]) var1);
}
protected void onProgressUpdate(@NotNull Integer... values) {
Intrinsics.checkParameterIsNotNull(values, "values");
Button var10000 = (Button) this.startButtonRef.get();
if (var10000 != null) {
Button startButton = var10000;
Intrinsics.checkExpressionValueIsNotNull(startButton, "startButton");
// StringCompanionObject var3 = StringCompanionObject.INSTANCE;
String var4 = this.executingNthIteration;
Object[] var5 = new Object[]{values[0], KtMainActivity.TOTAL};
String var9 = String.format(var4, Arrays.copyOf(var5, var5.length));
Intrinsics.checkExpressionValueIsNotNull(var9, "java.lang.String.format(format, *args)");
String var7 = var9;
startButton.setText((CharSequence) var7);
ViewGroup var10 = (ViewGroup) this.containerRef.get();
if (var10 != null) {
ViewGroup container = var10;
Intrinsics.checkExpressionValueIsNotNull(container, "container");
this.measureAndLayoutExactLength(container);
this.measureAndLayoutWrapLength(container);
}
}
}
// $FF: synthetic method
// $FF: bridge method
public void onProgressUpdate(Object[] var1) {
this.onProgressUpdate((Integer[]) var1);
}
protected void onPostExecute(@Nullable Void aVoid) {
TextView var10000 = (TextView) this.finishTextViewRef.get();
if (var10000 != null) {
TextView finishTextView = var10000;
Intrinsics.checkExpressionValueIsNotNull(finishTextView, "finishTextView");
finishTextView.setVisibility(View.VISIBLE);
Button var4 = (Button) this.startButtonRef.get();
if (var4 != null) {
Button startButton = var4;
Intrinsics.checkExpressionValueIsNotNull(startButton, "startButton");
startButton.setVisibility(View.GONE);
}
}
}
// $FF: synthetic method
// $FF: bridge method
public void onPostExecute(Object var1) {
this.onPostExecute((Void) var1);
}
private final void measureAndLayoutWrapLength(ViewGroup container) {
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(KtMainActivity.WIDTH, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(KtMainActivity.HEIGHT, View.MeasureSpec.AT_MOST);
container.measure(widthMeasureSpec, heightMeasureSpec);
container.layout(0, 0, container.getMeasuredWidth(), container.getMeasuredHeight());
}
private final void measureAndLayoutExactLength(ViewGroup container) {
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(KtMainActivity.WIDTH, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(KtMainActivity.HEIGHT, View.MeasureSpec.EXACTLY);
container.measure(widthMeasureSpec, heightMeasureSpec);
container.layout(0, 0, container.getMeasuredWidth(), container.getMeasuredHeight());
}
@NotNull
public final String getExecutingNthIteration() {
return this.executingNthIteration;
}
@NotNull
public final WeakReference getStartButtonRef() {
return this.startButtonRef;
}
@NotNull
public final WeakReference getFinishTextViewRef() {
return this.finishTextViewRef;
}
@NotNull
public final WeakReference getContainerRef() {
return this.containerRef;
}
public MeasureLayoutAsyncTask(@NotNull String executingNthIteration, @NotNull WeakReference startButtonRef, @NotNull WeakReference finishTextViewRef, @NotNull WeakReference containerRef) {
super();
Intrinsics.checkParameterIsNotNull(executingNthIteration, "executingNthIteration");
Intrinsics.checkParameterIsNotNull(startButtonRef, "startButtonRef");
Intrinsics.checkParameterIsNotNull(finishTextViewRef, "finishTextViewRef");
Intrinsics.checkParameterIsNotNull(containerRef, "containerRef");
this.executingNthIteration = executingNthIteration;
this.startButtonRef = startButtonRef;
this.finishTextViewRef = finishTextViewRef;
this.containerRef = containerRef;
}
}
}
D/Jet: layoutMeasureDurationNs: 267344
D/Jet: layoutMeasureDurationNs: 47708
D/Jet: layoutMeasureDurationNs: 647240
D/Jet: layoutMeasureDurationNs: 59636
D/Jet: layoutMeasureDurationNs: 50052
D/Jet: layoutMeasureDurationNs: 49739
D/Jet: layoutMeasureDurationNs: 75990
D/Jet: layoutMeasureDurationNs: 296198
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 894375
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 1248021
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 0
D/Jet: layoutMeasureDurationNs: 1290677
D/Jet: layoutMeasureDurationNs: 2936563
D/Jet: layoutMeasureDurationNs: 1387188
D/Jet: layoutMeasureDurationNs: 2325521
D/Jet: layoutMeasureDurationNs: 1940052
D/Jet: layoutMeasureDurationNs: 1539271
D/Jet: layoutMeasureDurationNs: 803750
D/Jet: layoutMeasureDurationNs: 1405000
D/Jet: layoutMeasureDurationNs: 1188437
D/Jet: layoutMeasureDurationNs: 1748802
D/Jet: layoutMeasureDurationNs: 3422240
D/Jet: layoutMeasureDurationNs: 1400677
D/Jet: layoutMeasureDurationNs: 2416094
D/Jet: layoutMeasureDurationNs: 1532864
D/Jet: layoutMeasureDurationNs: 1684063
D/Jet: layoutMeasureDurationNs: 1092865
D/Jet: layoutMeasureDurationNs: 1363177
D/Jet: layoutMeasureDurationNs: 1067188
D/Jet: layoutMeasureDurationNs: 1358333
D/Jet: layoutMeasureDurationNs: 2999895
D/Jet: layoutMeasureDurationNs: 2113021
D/Jet: layoutMeasureDurationNs: 1957395
D/Jet: layoutMeasureDurationNs: 1319740
D/Jet: layoutMeasureDurationNs: 2207239
D/Jet: layoutMeasureDurationNs: 1514167
D/Jet: layoutMeasureDurationNs: 949114
D/Jet: layoutMeasureDurationNs: 1691250
D/Jet: layoutMeasureDurationNs: 1387448
D/Jet: layoutMeasureDurationNs: 932552
D/Jet: layoutMeasureDurationNs: 1223802
D/Jet: layoutMeasureDurationNs: 2024740
D/Jet: layoutMeasureDurationNs: 1242292
D/Jet: layoutMeasureDurationNs: 2228230
D/Jet: layoutMeasureDurationNs: 1382083
D/Jet: layoutMeasureDurationNs: 2233282
D/Jet: layoutMeasureDurationNs: 1907187
D/Jet: layoutMeasureDurationNs: 2287552
D/Jet: layoutMeasureDurationNs: 776354
D/Jet: layoutMeasureDurationNs: 1225000
D/Jet: layoutMeasureDurationNs: 875417
D/Jet: layoutMeasureDurationNs: 1271302
D/Jet: layoutMeasureDurationNs: 1211614
D/Jet: layoutMeasureDurationNs: 1346459
D/Jet: layoutMeasureDurationNs: 1978854
D/Jet: layoutMeasureDurationNs: 2915677
D/Jet: layoutMeasureDurationNs: 1330573
D/Jet: layoutMeasureDurationNs: 2195364
D/Jet: layoutMeasureDurationNs: 775208
D/Jet: layoutMeasureDurationNs: 2492292
D/Jet: layoutMeasureDurationNs: 400104
D/Jet: layoutMeasureDurationNs: 2844375
D/Jet: layoutMeasureDurationNs: 1563750
D/Jet: layoutMeasureDurationNs: 3689531
D/Jet: layoutMeasureDurationNs: 2019323
D/Jet: layoutMeasureDurationNs: 1663906
D/Jet: layoutMeasureDurationNs: 1004531
D/Jet: layoutMeasureDurationNs: 738125
D/Jet: layoutMeasureDurationNs: 1299166
D/Jet: layoutMeasureDurationNs: 1223854
D/Jet: layoutMeasureDurationNs: 1942240
D/Jet: layoutMeasureDurationNs: 1392396
D/Jet: layoutMeasureDurationNs: 1906458
D/Jet: layoutMeasureDurationNs: 691198
D/Jet: layoutMeasureDurationNs: 2620468
D/Jet: layoutMeasureDurationNs: 1953229
D/Jet: layoutMeasureDurationNs: 1120365
D/Jet: layoutMeasureDurationNs: 3165417
D/Jet: layoutMeasureDurationNs: 537709
D/Jet: layoutMeasureDurationNs: 3019531
D/Jet: layoutMeasureDurationNs: 706250
D/Jet: layoutMeasureDurationNs: 1129115
D/Jet: layoutMeasureDurationNs: 539427
D/Jet: layoutMeasureDurationNs: 1633438
D/Jet: layoutMeasureDurationNs: 1784479
D/Jet: layoutMeasureDurationNs: 743229
D/Jet: layoutMeasureDurationNs: 1851615
D/Jet: layoutMeasureDurationNs: 851927
D/Jet: layoutMeasureDurationNs: 1847916
D/Jet: layoutMeasureDurationNs: 836718
D/Jet: layoutMeasureDurationNs: 2892552
D/Jet: layoutMeasureDurationNs: 1230573
D/Jet: layoutMeasureDurationNs: 3886563
D/Jet: layoutMeasureDurationNs: 2138281
D/Jet: layoutMeasureDurationNs: 2198021
D/Jet: layoutMeasureDurationNs: 1805885
D/Jet: layoutMeasureDurationNs: 2316927
D/Jet: layoutMeasureDurationNs: 1990937
D/Jet: layoutMeasureDurationNs: 2261041
D/Jet: layoutMeasureDurationNs: 2159010
D/Jet: layoutMeasureDurationNs: 666562
D/Jet: layoutMeasureDurationNs: 2332031
D/Jet: layoutMeasureDurationNs: 1061875
D/Jet: layoutMeasureDurationNs: 1879062
D/Jet: layoutMeasureDurationNs: 1411459
D/Jet: layoutMeasureDurationNs: 154635
复制代码
public class SampleApplication extends Application {
@Override
public void onCreate() {
registerActivityLifecycleCallbacks(new ActivityFrameMetrics.Builder()
.warningLevelMs(10) //default: 17ms
.errorLevelMs(10) //default: 34ms
.showWarnings(true) //default: true
.showErrors(true) //default: true
.build());
}
}
复制代码
E/FrameMetrics: Janky frame detected on KtMainActivity with total duration: 16.91ms
Layout/measure: 1.66ms, draw:2.51ms, gpuCommand:3.13ms others:9.61ms
Janky frames: 72/107(67.28972%)
E/FrameMetrics: Janky frame detected on KtMainActivity with total duration: 15.47ms
Layout/measure: 1.00ms, draw:2.05ms, gpuCommand:3.44ms others:8.98ms
Janky frames: 73/108(67.59259%)
E/FrameMetrics: Janky frame detected on KtMainActivity with total duration: 15.09ms
Layout/measure: 1.30ms, draw:1.44ms, gpuCommand:2.91ms others:9.44ms
Janky frames: 74/110(67.27273%)
****
复制代码