安卓开发过程中, 很多地方都要使用 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;
}
}
标签:<application
android:name="me.zipstream.test.MyApplication"
... ...
... ... >
... ...
application>
注意: 指定 MyApplication 时一定要加上完整的包名.
* 这样, 就可以在项目中的任何地方使用 Context, 只需要调用一下 MyApplication.getContext()
方法就好.
可以借助 Intent 来启动活动, 发送广播, 启动服务等, 可以使用 putExtra()
方法来添加要传递的数据. 但是这种方式传递的数据类型是有限的, 如果想要传递一个自定义的对象就会无从下手.
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");
将一个完整的对象进行分解, 分解后的每一部分都是 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 就可以了.