Android13——Advanced Trick

Advanced Trick

全局获取Context的技巧

目前,我们还没有为得不到Context而发愁过,因为我们许多的操作是在activity中进行的,而activity本身就是一个Context对象。但是,当应用程序的架构逐渐开始复杂起来的时候,很多逻辑代码将脱离Activity类,但此时你又恰恰需要使用Context,也许这个时候你就很难受了。

解决方法:

  • 传递一个Context进来。
  • 利用android提供的Application类。

android提供的application类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。而我们可以制定一个自己的application类,以便于管理程序内一些全局的状态信息,比如全局Context。

比如创建一个Toast工具类(这个是为了模仿kotlin中的扩展函数的(infix function)的:

public class ToastUtil {
    public static void showToast(@NotNull String receiver){
        Toast.makeText(MyApplicatoin.context,receiver,Toast.LENGTH_SHORT);
    }
}

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ToastUtil.showToast("abc");
    }
}

使用Intent传递对象

我们可以借助Intent来启动activity、启动service、发送广播等。在进行上述操作的时候,我们还可以在intent中添加一些附加数据,已达到传值的效果,但是明显传值的数据类型非常有限,但是当你想要传递一些自定义对象的时候,就会发现无从下手。下面学习一下使用intent传递对象的技巧。

使用Intent来传递对象通常有两种实现方式:

  • serializable:序列化,表示将一个对象转化成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储在本地。
  • parcelable:将一个完整的对象进行分解,而分解后的每一部分都是Intent支持的数据类型,从而实现传递对象的功能。

serializable方式

实现方式:

  • 对象所在的类实现Serializable这个接口。
  • 调用intent的getSerializableExtra()方法来获取通过参数传递过来的序列号对象,接着再将他向下转型成相应对象。【序列号=>反序列化】

parcelable方式

实现方式,对象所在的类实现Parcelable接口:

  • 重写describeContents()writeToParcel()两个方法
  • 实现CREATOR匿名类:重写createFromParcel()newArray()两个方法。

具体代码如下:

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {
    public String name = "";
    public int age = 0;

    /**
     * 反序列化需要的构造函数
     * @param in
     */
    public Person(Parcel in) {
        this.age = in.readInt();
        this.name = in.readString();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };


    /**
     * @return 内容接口描述,默认返回0就可以了
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 序列化的函数
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name); // 写入nme
        dest.writeInt(age); // 写入age
    }
}

定制自己的日志工具

新建一个LogUtil单例类:

/**
 * cite:https://blog.csdn.net/huantai3334/article/details/104504208
 *
 * java中工具类应该写成单例,还是全是静态方法的类?
 * 说静态类好的:
 * 1. 静态类不用引用就能调用,而单例需要有对象的引用,因此节约资源
 * 2.静态类方便,随处可用;而单例必须有引用,需要注入或者Object.getInstance()
 *
 * 说单例好的:
 * 1.单例模式的类是普通的类,它具有面向对象的特性,方便扩展
 * 2.对于有配置的工具类,可以轻松的创建多个不同配置的单例对象(想起我主导的另一个项目就存在5-6个redis数据源,如果使用静态类就是灾难)
 *
 * 因此,我得出以下结论:
 * 如果没有配置信息的工具类,当然是静态类好,随处调用,不需引用爽得不要不要的。
 * 如果有配置信息的工具类,最好还是使用单例模式。
 *
 */
public class LogUtil {
    private static final int VERBOSE = 1;
    private static final int DEBUG = 2;
    private static final int INFO = 3;
    private static final int WARN = 4;
    private static final int ERROR = 5;

    private static int level = VERBOSE;

    public static void v(String tag, String msg){
        if(level<=VERBOSE){
            Log.v(tag,msg);
        }
    }
    public static void d(String tag, String msg){
        if(level<=DEBUG){
            Log.d(tag,msg);
        }
    }
    public static void i(String tag, String msg){
        if(level<=INFO){
            Log.i(tag,msg);
        }
    }
    public static void w(String tag, String msg){
        if(level<=WARN){
            Log.w(tag,msg);
        }
    }
    public static void e(String tag, String msg){
        if(level<=ERROR){
            Log.e(tag,msg);
        }
    }

}

深色主题

Android10.0系统中,google引入了深度主题这一特性,从而让夜间模式正式成为了官方支持的功能。具体支持步骤如下:

  • 首先在自己的android手机中setting->Display->Dark theme中对深色追进行开启和关闭。

    img img
  • 对自己编写的程序进行适配【略】

    • 最简单的一种适配方式就是使用Force Dark,他是一种能让应用程序快速适配深色主题,并不需要编写额外代码的方式。
    • 手动实现 =>AppCompat库内中的主题包含浅色主题和深色主题两类。
原文地址:https://www.cnblogs.com/SsoZhNO-1/p/14197867.html