处理屏幕旋转导致的重建,单例对象,StringBuilder进行拼接,ProGurad 混淆,VectorDrawable 及 AnimatedVectorDr

95 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

处理屏幕旋转导致的重建

当屏幕发生旋转时,如果我们没有在AndroidManifest.xml中,对其configChanges属性进行声明,那么就会导致Activity进行重建,此时,就需要重新加载Activity所需要展示的数据。

在EditText控件中输入后,当屏幕旋转后,里面的内容就会不见,activity进行了重建,但是checkBox不会重建。

此时,我们就可以对其进行如下的声明:

android:configChanges="keyboardHidden|orientation|screenSize"

接着在ActivityonConfigurationChanged进行监听,对布局进行相应的改变,而不需要重新加载数据。

单例对象在需要的时候初始化

在使用单例时,我们应当仅在使用到该单例时才去初始化它,这里我们可以通过“静态初始化会在类被加载时触发”这一原理,来实现懒加载。

public class OptSingleton {
    
    private OptSingleton() {}
    
    public static OptSingleton getInstance() {
        return Holder.INSTANCE;
    }
    
    private static class Holder {
        public static final OptSingleton INSTANCE = new OptSingleton();
    }
}

采用StringBuilder的方式进行拼接:

    public static void goodString() {
        StringBuilder result = new StringBuilder("result");
        String append = "append";
        for (int i = 0; i < (1 << 20); i++) {
            result.append(append);
        }
    }

减少不必要的异常

在某些时候,如果我们能预见到某些有可能会发生异常的场景,那么提前进行判断,将可以避免由于异常所带来的代价,以启动第三方应用为例,我们可以先判断该intent所对应的应用是否存在,再去启动它,而不是等到异常发生时再去捕获:

    public static void startApp(Context context) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("www.qq.com"));
        intent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
        if (intent.resolveActivity(context.getPackageManager()) == null) {
            return;
        }
        try {
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

使用 ProGurad 优化代码

通过ProGuard对代码进行优化、压缩、混淆,可以移除不需要的代码、重命名类、域与方法等,做法就是在buildTypes的指定类型下增加下面的代码:

    buildTypes {
        release {
            //对于release版本采用进行混淆。
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        }
        debug {
            //对于debug版本不混淆。
            minifyEnabled false
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        }

这里的混淆规文件有两份,如果有多份,那么可以使用逗号分隔,第一个是Android自带的混淆文件,而第二个则是应用自定义的混淆规则文件,关于混淆文件的语法,

VectorDrawable 及 AnimatedVectorDrawable 使用详解:

www.jianshu.com/p/723dc385e…

对于只执行一次的后台任务,使用 IntentService 替代 Service

当我们需要将某些任务的生命周期和Activity分离开来,那么一般会使用Service,但是Service就需要我们进行手动管理,如果忘记,那么将会导致额外的内存占用,并且拥有Service进程的oom_adj值一般会高于没有Service的进程,系统会更倾向于将它保留。

对于一些短时的后台任务,我们可以考虑采用IntentService,它的onHandleIntent回调是在异步线程中执行的,并且任务执行完毕后,该Service会自动销毁,不需要手动管理。

 ViewStub 动态加载布局

进行布局复用:

 SpannableStringBuilder 替换多个 TextView 

 LinearLayout 自带的分割线:

    android:showDividers="beginning|end|middle"

 Space 控件进行合理的占位:

  <android.support.v4.widget.Space
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight="1"/>

 TextView 的 drawableLeft/drawableTop 

 AsyncLayoutInflater 异步加载;

 public void onClick(View v) {
                AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(OptActivity.this);
                asyncLayoutInflater.inflate(R.layout.layout_async, root, new AsyncLayoutInflater.OnInflateFinishedListener() {

                    @Override
                    public void onInflateFinished(View view, int resId, ViewGroup parent) {
                        parent.addView(view);
                    }
                });