简易新闻性能优化篇(简易新闻二十二)

本文介绍简易新闻App的性能优化方法,包括使用ProGuard简化代码、Application启动时的懒加载优化和利用线程池进行异步优化,有效缩短了启动时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于

其实关于app的优化我也是学习大佬写的文章,然后自己实践并记录下来,或是记录一些踩坑的点。简易新闻的优化方向还有很多,包括一些代码逻辑,以及使用的控件等等,而且冷启动的优化下面说的也不是很全面,但是现在暂时不想往下面补充了,

使用ProGuard简化代码

关于proguard的详解可以参考这篇博文 《关于proguard,你需要知道的全部》
第一步我们需要在项目的build中开启混淆功能,如下:

    buildTypes {
        release {
            minifyEnabled true //混淆
            shrinkResources true //去除无用资源
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        
        }
    }

然后修改我们的proguard-rules.pro文件:
我这里是直接把我写的项目的混淆拿出来了,基本上需要自己需改的地方包括Gson的混淆、第三方引用的混淆,其他的基本一样。

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# 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
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-ignorewarnings

-dontshrink
#指定代码的压缩级别
-optimizationpasses 5

#包明不混合大小写
-dontusemixedcaseclassnames

#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses

 #优化  不优化输入的类文件
-dontoptimize

 #不做预校验
-dontpreverify

 #混淆时是否记录日志
-verbose

 # 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
#保护注解
-keepattributes *Annotation*
#内部类
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-dontoptimize
########################反射类不被混淆三部曲##################################
#过滤泛型
-keepattributes Signature
# 保留R下面的资源
# 不混淆R类里及其所有内部static类中的所有static变量字段,$是用来分割内嵌类与其母体的标志
-keep public class **.R$*{
   public static final int *;
}
#实体反射类不被混淆
#-keep public class com.henry.arron.dtxj.WellMonitorTask.WM_ListDetail_Bean{*;}
#-keep public class com.henry.arron.dtxj.WaterQualityMonitorTask.WQM_ListDetail_Bean{*;}


########################################################################

# 保持哪些类不被混淆
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-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.database.sqlite.SQLiteOpenHelper{*;}
-keep public class com.android.vending.licensing.ILicensingService



#无视warning
-ignorewarnings
# 保留support下的所有类及其内部类
-keep class android.support.** {*;}

# 保留继承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**


-dontwarn android.support.annotation.Keep
#保留类内部使用@keep 注解的成员变量
-keep @android.support.annotation.Keep class **{
 @android.support.annotation.Keep <fields>;
}

# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}

# 保留在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);
}

# 保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$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();
}

# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
}
#
#----------------------------- WebView(项目中没有可以忽略) -----------------------------
#
#webView需要进行特殊处理
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
   public *;
}
-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, jav.lang.String);
}
#在app中与HTML5的JavaScript的交互进行特殊处理
#我们需要确保这些js要调用的原生方法不能够被混淆,于是我们需要做如下处理:
-keepclassmembers class com.ljd.example.JSInterface {
    <methods>;
}

#
# ----------------------------- 其他的 -----------------------------
#
# 删除代码中Log相关的代码
-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(...);
}

# 保持测试相关的代码
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**

#com.github.ljw124:LogLibrary:1.0.5
-dontwarn org.apache.log4j.**
-keep class org.apache.log4j.** { *; }
#--------------------------------------------------------------------

#butterknife
-dontwarn butterknife.internal.**
-keep class butterknife.** { *; }
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }


#greendao
  -keep class org.greenrobot.greendao.**{*;}
  -keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { public static java.lang.String TABLENAME;}
  -keep class **$Properties
  -keep class org.greenrobot.greendao.database.DatabaseOpenHelper.EncryptedHelper{*;}

  # OkHttp3
  -dontwarn okhttp3.logging.**
  -keep class okhttp3.internal.**{*;}
  -dontwarn okio.**

  #okhttp3.x
  -dontwarn okhttp3.**
  -dontwarn okio.**
  -dontwarn javax.annotation.**
  -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
  #Glide
  -keep public class * implements com.bumptech.glide.module.GlideModule
  -keep public class * extends com.bumptech.glide.module.AppGlideModule
  -keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
    **[] $VALUES;
    public *;
  }

  # Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

# RxJava RxAndroid
-dontwarn io.reactivex.**
-keep class io.reactivex.** {*;}

  -dontwarn sun.misc.**
  -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
      long producerIndex;
      long consumerIndex;
  }
  -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
      rx.internal.util.atomic.LinkedQueueNode producerNode;
  }
  -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
      rx.internal.util.atomic.LinkedQueueNode consumerNode;
  }
# DJI
-dontwarn okio.**
-dontwarn org.bouncycastle.**
-keep class org.bouncycastle.** { *; }

-dontwarn dji.**
-keep class dji.** { *; }

-dontwarn com.dji.**
-keep class com.dji.** { *; }

-keep,allowshrinking class * extends dji.publics.DJIUI.** {
    public <methods>;
}

-keep class net.sqlcipher.** { *; }

-keep class net.sqlcipher.database.* { *; }


-keep class com.google.** { *; }


-keep,allowshrinking class org.** { *; }

-keep class com.squareup.wire.** { *; }

-keep class sun.misc.Unsafe { *; }

-keep class com.secneo.** { *; }

-keepclasseswithmembers,allowshrinking class * {
    native <methods>;
}

-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep class android.support.v7.widget.SearchView { *; }
-keepclassmembers public class * extends android.view.View {
    void set*(***);
    *** get*();
}
-keep class android.media.** { *; }
-keep class okio.** { *; }


#Arouter
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}

# If you use the byType method to obtain Service, add the following rules to protect the interface:
-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider

# If single-type injection is used, that is, no interface is defined to implement IProvider, the following rules need to be added to protect the implementation
-keep class * implements com.alibaba.android.arouter.facade.template.IProvider

# If @Autowired is used for injection in non-Activity classes, add the following rules to prevent injection failures
-keepnames class * {
    @com.alibaba.android.arouter.facade.annotation.Autowired <fields>;
}

#esri关于混淆的代码
-dontwarn com.esri.**
-keep class com.esri.** {*;}
-dontwarn org.codehaus.jackson.**
-keep class org.codehaus.jackson.** {*;}
-dontwarn org.codehaus.jackson.**
-keep class org.codehaus.jackson.** {*;}
-dontwarn jcifs.**
-keep class jcifs.** {*;}


#-keep interface com.esri.** { *; }
#-dontwarn org.codehaus.jackson.map.ext.**
#-dontwarn jcifs.http.**

#高德开放平台上关于api混淆的代码
#3D 地图 V5.0.0之后:
-dontwarn com.amap.api.maps.**
-keep   class com.amap.api.maps.**{*;}
-dontwarn com.autonavi.**
-keep   class com.autonavi.**{*;}
-dontwarn com.amap.api.trace.**
-keep   class com.amap.api.trace.**{*;}

-dontwarn com.amap.api.location.**
-keep class com.amap.api.location.**{*;}
-dontwarn com.amap.api.fence.**
-keep class com.amap.api.fence.**{*;}
-dontwarn com.autonavi.aps.amapapi.model.**
-keep class com.autonavi.aps.amapapi.model.**{*;}
#搜索
-dontwarn com.amap.api.services.**
-keep   class com.amap.api.services.**{*;}
#JPush
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }

-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }

#Material Dialog提示框
-dontwarn com.afollestad.**
-keep class com.afollestad.** { *; }

#DHVideo 大华视频监控
-dontwarn com.dh.**
-keep class com.dh.** { *; }

#HCVideo 海康威视视频监控
# 海康威视视频取流播放相关库的混淆配置
-keep class org.MediaPlayer.PlayM4.** {*;}
-keep class com.hikvision.netsdk.** {*;}
-keep class com.hikvision.audio.** {*;}
-keep class hik.common.isms.hpsclient.** {*;}
-keep class com.hikvision.open.hikvideoplayer.** {*;}


#litepal数据库不能被混淆
-keep class org.litepal.** {*;}
-keep class * extends org.litepal.crud.DataSupport {*;}

#EventBus
-keepclassmembers class ** {
    public void onEvent*(**);
}
-keepclassmembers class ** {
public void xxxxxx(**);
}

#eventbus 3.0
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#YS Cloud 萤石平台SDK
-dontwarn com.ezviz.**
-keep class com.ezviz.** { *;}

#MPAndroidChart
-dontwarn com.github.mikephil.charting.**
-keep class com.github.mikephil.charting.** { *;}

#SmartTable
-dontwarn com.bin.david.form.**
-keep class com.bin.david.form.**{  *;  }
#SmartGo
-keep class * implements pers.victor.smartgo.SmartGoInjector
-keep class * implements pers.victor.smartgo.SmartPathInjector
-keep class * implements pers.victor.smartgo.InstanceInjector

-dontwarn com.videogo.**
-keep class com.videogo.** { *;}

-dontwarn org.MediaPlayer.PlayM4.**
-keep class org.MediaPlayer.PlayM4.** { *;}

-dontwarn javax.validation.**
-keep class javax.validation.** { *;}

-dontwarn com.sun.jna.**
-keep class com.sun.jna.**{*;}

-dontwarn com.ezvizuikit.open.**
-keep class com.ezvizuikit.open.**{*;}

-dontwarn com.google.gson.**
-keep class com.google.gson.**{*;}

-dontwarn com.google.zxing.**
-keep class com.google.zxing.**{*;}

#utils
-keep class com.blankj.utilcode.** { *; }
-keepclassmembers class com.blankj.utilcode.** { *; }
-dontwarn com.blankj.utilcode.**

# Gson
-keepattributes Annotation
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-keep class com.google.gson.examples.android.model.** { *; }
# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。
# 将下面替换成自己的实体类
-keep class com.example.frametest.json.** { *; }
#Mob短信验证
-keep class com.mob.**{*;}
-keep class cn.smssdk.**{*;}
-dontwarn com.mob.**

#引用mars的xlog,混淆配置
-keep class com.tencent.mars.** {
 public protected private *;
}
#和风天气
# 排除okhttp
  -dontwarn com.squareup.**
  -dontwarn okio.**
  -keep public class org.codehaus.* { *; }
  -keep public class java.nio.* { *; }

# 排除HeWeather
  -dontwarn interfaces.heweather.com.interfacesmodule.**
  -keep class interfaces.heweather.com.interfacesmodule.** { *;}


#####混淆保护自己项目的部分代码以及引用的第三方jar包library#######
#项目特殊处理代码
#多图选择器不能被混淆
-dontwarn me.nereo.multi_image_selector.**
-keep class me.nereo.multi_image_selector.* {*;}
-keep class me.nereo.multi_image_selector.adapter.* {*;}
-keep class me.nereo.multi_image_selector.bean.* {*;}
-keep class me.nereo.multi_image_selector.utils.* {*;}
-keep class me.nereo.multi_image_selector.view.* {*;}



#Glide不能被混淆
-dontwarn com.bumptech.**
-keep class com.bumptech.**{  *;  }

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

-dontwarn com.cazaea.**
-keep class com.cazaea.**{  *;  }




-dontwarn com.scwang.**
-keep class com.scwang.**{  *;  }

-dontwarn com.davidecirillo.**
-keep class com.davidecirillo.**{  *;  }

-dontwarn com.squareup.**
-keep class com.squareup.**{  *;  }

-dontwarn org.xutils.**
-keep class org.xutils.**{  *;  }

-dontwarn com.xujiaji.**
-keep class com.xujiaji.**{  *;  }

-dontwarn com.android.**
-keep class com.android.**{*;}

-dontwarn android.arch.**
-keep class android.arch.**{*;}

-dontwarn com.bumptech.**
-keep class com.bumptech.**{*;}

-dontwarn org.**
-keep class org.**{*;}

-dontwarn javax.**
-keep class javax.**{*;}

-dontwarn android.backport.**
-keep class android.backport.**{*;}

-dontwarn com.wx.**
-keep class com.wx.**{*;}

-dontwarn com.jauker.widget.**
-keep class com.jauker.widget.**{  *;  }


-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.**{  *;  }






##记录生成的日志数据,gradle build时在本项目根目录输出##

#apk 包内所有 class 的内部结构
-dump class_files.txt
#未混淆的类和成员
-printseeds seeds.txt
#列出从 apk 中删除的代码
-printusage unused.txt
#混淆前后的映射
-printmapping mapping.txt

########记录生成的日志数据,gradle build时 在本项目根目录输出-end######

Application启动优化

在学习优化之前,先看一下我们的app的启动消耗时间。
这里我们使用很普遍的计算耗时方法:adb 命令统计
当然了在使用之前,需要配置一下它的环境变量,如下:
配置android\SDK\android-sdk-windows\platform-tools这个目录到ptah中:
在这里插入图片描述
然后我们输入如下代码到android studio中的Terminal中:

adb shell am start -S -W 包名/启动类的全限定名 -S 表示重启当前应用

我们先看一下我们项目的包名,类名:
在这里插入图片描述
其中包名就是:com.example.logintest,类名我们把重启进入的第一个页面作为类名。
成功输出结果:

E:\PersonalSVN\Blog>adb shell am start -S -W com.example.logintest/com.example.app.Tools.SplashActivity
Stopping: com.example.logintest
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.logintest/com.example.app.Tools.SplashActivity }
Status: ok
Activity: com.example.logintest/com.example.app.Tools.SplashActivity
ThisTime: 1620
TotalTime: 1620
WaitTime: 1634
Complete

  1. ThisTime : 最后一个 Activity 的启动耗时(例如从 LaunchActivity - >MainActivity「adb命令输入的Activity」 , 只统计 MainActivity 的启动耗时)
  2. TotalTime : 启动一连串的 Activity 总耗时.(有几个Activity 就统计几个)
  3. WaitTime : 应用进程的创建过程 + TotalTime .

这里我们只需要参考thisTime即可。优化它就是优化冷启动时间。

优化方式一 懒加载

    @Override
    public void onCreate() {
        super.onCreate();
        //获取全局context
        context = getApplicationContext();
        //初始化
        instance = this;
        //懒加载
        new Thread(){
            @Override
            public void run() {
                super.run();    
                //这里放入自己的三方SDK    
                //......初始化第三方SDK
                MultiDex.install(getApplicationContext());
                // 穿山甲SDK初始化
                // 强烈建议在应用对应的Application#onCreate()方法中调用,避免出现content为null的异常
                TTAdManagerHolder.init(getApplicationContext());
                //如果明确某个进程不会使用到广告SDK,可以只针对特定进程初始化广告SDK的content
                //if (PROCESS_NAME_XXXX.equals(processName)) {
                //   TTAdManagerHolder.init(this)
                //}
                TTAdSdk.init(context,
                        new TTAdConfig.Builder()
                                .appId("5043758")
                                .useTextureView(false) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
                                .appName("简易新闻")
                                .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
                                .allowShowNotify(true) //是否允许sdk展示通知栏提示
                                .allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
                                .debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
                                .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允许直接下载的网络状态集合
                                .supportMultiProcess(false) //是否支持多进程,true支持
                                //  .httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
                                .build());
            }
        }.start();
       }

重新输入adb命令查看耗时:

E:\PersonalSVN\Blog>adb shell am start -S -W com.example.logintest/com.example.app.Tools.SplashActivity
Stopping: com.example.logintest
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.logintest/com.example.app.Tools.SplashActivity }
Status: ok
Activity: com.example.logintest/com.example.app.Tools.SplashActivity
ThisTime: 1555
TotalTime: 1555
WaitTime: 1574
Complete

没用懒加载之前是1620,使用懒加载后是1555,优化了,虽然不多。

优化方式二 线程池异步优化

核心思想:子线程分担主线程任务,并行减少执行时间。
代码如下:

  //计算线程数量
  private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = Math.max(2,Math.min(CPU_COUNT-1,4));
    private CountDownLatch mCountDownLatch = new CountDownLatch(1);
     @Override
    public void onCreate() {
        super.onCreate();
        //获取全局context
        context = getApplicationContext();
        //初始化
        instance = this;
        //线程异步优化
        ExecutorService pool = Executors.newFixedThreadPool(CORE_POOL_SIZE);
        pool.submit(new Runnable() {
            @Override
            public void run() {

                //......初始化第三方SDK
                // 穿山甲SDK初始化
                // 强烈建议在应用对应的Application#onCreate()方法中调用,避免出现content为null的异常
                TTAdManagerHolder.init(getApplicationContext());
                //如果明确某个进程不会使用到广告SDK,可以只针对特定进程初始化广告SDK的content
                //if (PROCESS_NAME_XXXX.equals(processName)) {
                //   TTAdManagerHolder.init(this)
                //}
                TTAdSdk.init(context,
                        new TTAdConfig.Builder()
                                .appId("5043758")
                                .useTextureView(false) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
                                .appName("简易新闻")
                                .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
                                .allowShowNotify(true) //是否允许sdk展示通知栏提示
                                .allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
                                .debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
                                .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允许直接下载的网络状态集合
                                .supportMultiProcess(false) //是否支持多进程,true支持
                                //  .httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
                                .build());
                ////调用一次countDown,防止当我们需要在oncreate中完成这个初始化时的错误
                mCountDownLatch.countDown();
            }
        });
        pool.submit(new Runnable() {
            @Override
            public void run() {
                MultiDex.install(getApplicationContext());
            }
        });
        try {
            //如果await之前没有调用countDown那么就会一直阻塞在这里
            mCountDownLatch.await();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

再次用adb,运行时间再次缩减:

E:\PersonalSVN\Blog>adb shell am start -S -W com.example.logintest/com.example.app.Tools.SplashActivity
Stopping: com.example.logintest
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.logintest/com.example.app.Tools.SplashActivity }
Status: ok
Activity: com.example.logintest/com.example.app.Tools.SplashActivity
ThisTime: 1337
TotalTime: 1337
WaitTime: 1345
Complete

当然了,不是说一定第二种比第一种好,各有优劣。
本篇到此就结束了,关于简易新闻的源码以及一些新的功能,要往后面拖一拖了,比如马上要实现的夜间模式(动态切换,代码优化,listview切换成Recycleview等),包括考虑新增用户注册,登录(支持邮箱验证注册),自定义版本更新(不用第三方更新)以及热更新!(近期推出热更新学习文章)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪の星空朝酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值