這篇文章是將好久以來看過的文章,包括本身寫的一些測試代碼的總結.屬於筆記的性質,沒有面面俱到,一些本身相對熟悉的點可能會略過.
最開始看到的性能優化的文章,就是胡凱的優化典範系列,後來又陸續看過一些人寫的,我的以爲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%)
****
複製代碼