《第一行代码》读书笔记(十二)----高级技巧

全局获取 Context 的技巧

安卓开发过程中, 很多地方都要使用 Context , 比如:
弹出 Toast
启动活动
发送广播
操作数据库
使用通知
……

遇到的问题是, 怎么在一个脱离了 Activity 的类中获取到 Context 对象?
在 Android 中, 提供了一个 Application 类, 当应用启动时, 系统会自动将这个类进行初始化. 我们可以定制一个自己的 Application 类, 以便管理程序内一些全局的状态信息, 比如全局的 Context.

如何定制自己的 Application 类?
* 首先创建一个类继承自 Application :

public class MyApplication extends Application {

    private static Context context;

    //重写 onCreate() 方法, 获取一个应用程序级别的 Context 对象
    @Override
    public void onCreate() {
        context = getApplicationContext();
    }

    //对外提供一个静态方法, 供其他类适用
    public static Context getContext() {
        return context;
    }
}
  • 接着要告知系统, 程序启动时应该初始化的是 MyApplication 类, 而不是默认的 Application 类. 修改 AndroidManifest.xml 文件的 标签:
<application
    android:name="me.zipstream.test.MyApplication"
    ... ...
    ... ... >
    ... ...
application>

注意: 指定 MyApplication 时一定要加上完整的包名.
* 这样, 就可以在项目中的任何地方使用 Context, 只需要调用一下 MyApplication.getContext() 方法就好.

使用 Intent 传递对象

可以借助 Intent 来启动活动, 发送广播, 启动服务等, 可以使用 putExtra() 方法来添加要传递的数据. 但是这种方式传递的数据类型是有限的, 如果想要传递一个自定义的对象就会无从下手.

Serializable 方式

Serializable 是序列化的意思, 表示将一个对象转换成可存储或可传输的状态. 序列化之后的对象可以在网络上传输, 也可以存储到本地. 序列化的方法, 让一个类实现 Serializable 这个接口.

比如, 有一个 Person 类, 包含 name 和 age 两个字段. 现在序列化:

public class Person implements Serializable {

    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

在一个活动中使用 Intent 传递对象给另一个活动就可以写成:

Person person = new Person();
person.setName("Tom");
person.setAge(20);

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person_data", person);

startActivity(intent);

在另一个活动中取出对象:

Person person = (Person) getIntent().getSerializableExtra("person_data");

Parcelable 方式

将一个完整的对象进行分解, 分解后的每一部分都是 Intent 所支持的数据类型, 从而实现对象的传递.

Person 类可以这样写:

public class Person implements Parcelable {

    private String name;
    private int age;

    ...

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);//写出 name
        dest.writeInt(age);//写出 age
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){

        @Override
        public Person createFromParcel(Parcel source) {
            Person person = new Person();
            person.name = source.readString();//读取 name
            person.age = source.readInt();//读取 age
            //注意, 上两行代码的顺序要和刚才写出的顺序完全相同

            return person;
        }

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

在一个活动中传递这个对象给另一个活动与 Seriliazable 方式的代码一样.

在另一个活动中取出这个对象的代码:

Person person = (Person) getIntent().getParcelableExtra("person_data");

定制自己的日志工具

需求: 开发过程中用于调试的日志, 在项目正式上线后如何屏蔽掉?

新建一个 LogUtil 类:

public class LogUtil {

    public static final int VERBOSE = 1;
    public static final int DEBUG = 2;
    public static final int INFO = 3;
    public static final int WARN = 4;
    public static final int ERROR = 5;
    public static final int NOTHING = 6;

    public static final 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);
        }
    }
}

这样, 打印日志的语句:

LogUtil.d("TAG", "debug log");

我们只需修改 LEVEL 常量的值, 就可以控制日志的打印了. 在开发阶段将 LEVEL 指定成 VERBOSE, 项目正式上线后, 将 LEVEL 指定成 NOTHING 就可以了.

你可能感兴趣的:(Android)