一、全局获取Context技巧。
在项目任何地方都轻松获取Context。
Android提供了一个Application类,每当程序启动时,系统会自动将这个类进行初始化,我们可以定制一个自己的Application类,以便管理程序内的一些全局状态信息,比如Context。
1、创建一个MyApplication类继承自Application。
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
// getApplicationContext()方法得到应用级别的Context
context = getApplicationContext();
}
public static Context getContext(){
return context;
}
}
2、在AndroidManifest中的
……
……
3、如果想在项目任何地方使用Context,只需调用MyApplication. getContext()即可。
二、使用Intent传递对象。
(一)Serializable
Serializable是序列化的意思,表示将一个对象转换成可储存或可传输的状态。序列化后的对象可以在网络上进行传输,也可以储存到本地,序列化方法只需让该类实现Serializable接口即可。
1、创建Person类,添加name与age字段,并实现Serializable接口。
public class Person implements Serializable {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、使用时,创建Person实例,然后直接将其传入到putExtra()方法中。
Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.this);
intent.putExtra("person_data", person);
startActivity(intent);
3、在SecondActivity中添加。
Person person = (Person) getIntent().getSerializableExtra("person_data");
(二)Parcelable
Parcelable方式的原理是将一个完整的对象分解,而分解后的每一部分都是Intent所支持的数据类型,这样就实现了传递对象的功能。
1、创建People类,添加name与age字段,并实现Parcelable接口。
public class People implements Parcelable {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//重写describeContents()方法,返回0即可
@Override
public int describeContents() {
return 0;
}
//重写writeToParcel()方法调用Parcel的writeXxx()方法将People类中的字段一一写出。
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeInt(age);
}
//创建一个名为CREATOR的常量,并创建一个Parcelable.Creator接口的实现,泛型类型指定为People。
public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
//重写createFromParcel()方法调用Parcel的readXxx()方法读取字段,其中读取顺序一定要和写出顺序完全一致。
@Override
public People createFromParcel(Parcel parcel) {
People people = new People();
people.name = parcel.readString();
people.age = parcel.readInt();
return people;
}
//重写newArray()方法返回size大小数组
@Override
public People[] newArray(int size) {
return new People[size];
}
};
}
2、使用时,创建People实例,然后直接将其传入到putExtra()方法中。
People people = new People();
people.setName("Jack");
people.setAge(22);
Intent intent = new Intent(FirstActivity.this, SecondActivity.this);
intent.putExtra("people_data", people);
startActivity(intent);
3、在SecondActivity中添加。
People people = (People) getIntent().getParcelableExtra("people_data");
三、定制自己的日志工具
传统日志无法自由控制日志的打印,如当程序处于开发阶段就让日志打印出来,当程序上线则把日志全部屏蔽。
1、定制自己的日志工具,新建LogUtil类。
public class LogUtil {
//定义6个整型常量
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;
//静态变量level设置打印级别,只有当level的值小于或等于对应日志级别时,才会将日志打印
public static int level = VERBOSE;
//提供5个日志打印方法
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);
}
}
}
2、使用该日志工具,打印DEBUG级别或WARN级别。
LogUtil.d(“TAG”, “debug log”);
LogUtil.w(“TAG”, “warn log”);
此时在开发阶段将level指定为VERBOSE,项目上线时将level指定为NOTHING即可。
四、创建定时任务
(一)Alarm机制
Alarm具有唤醒CPU的功能,它可以保证大多数情况下需要执行定时任务时CPU都能正常工作。
用法:
1)getSystemService()方法传入Context.ALARM_SERVICE参数,获取AlarmManager实例。
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
2)调用AlarmManager的set()方法设置一个定时任务。
long triggerAtTime = SystemClock.elapsedRealtime() + 10 * 1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);
其中set()方法的第一个参数用于指定AlarmManager的工作类型,第二个参数为定时任务触发的时间,以毫秒为单位。第三个参数为PendingIntent,一般调用getService()或getBroadcast()获取一个服务或广播的PendingIntent。
1、新建一个LongRunningService服务,将触发定时任务的代码写到onStartCommand()中。
public class LongRunningService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int anHour = 60 * 60 * 1000;
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this, LongRunningService.class);
PendingIntent pi = PendingIntent.getService(this, 0 ,i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
return super.onStartCommand(intent, flags, startId);
}
}
2、启动定时服务时调用如下代码。
Intent intent = new Intent(context, LongRunningService.class);
context .startActivity(intent);
(二)Doze模式
Doze模式可以及大幅度地延长电池使用寿命,当用户设备是Android6.0以上时,如果该设备未插接电源,处于静止状态,并且屏幕关闭了一段时间后,就会进入Doze模式,在Doze模式下,系统会对CPU、网络、Alarm等活动进行限制,从而延长电池寿命。系统不会一直处于Doze模式,而是间歇性地退出Doze模式一小段时间。随着设备进入Doze模式的时间越长,间歇性退出Doze模式的时间间隔也会越长。
Doze模式下:
1)网络访问被禁止。
2)系统忽略唤醒CPU或屏幕操作
3)系统不再执行WIFI扫描
4)系统不再执行同步任务
5)Alarm任务将会在下次退出Doze模式时执行
五、多窗口模式
多窗口模式允许在同一个屏幕同时打开两个应用程序。
进入多窗口模式:
1)Overview列表界面长按任意一个活动标题,将该活动拖动到屏幕突出显示的区域,即可进入多窗口模式。
2)打开任意程序,长按Overview,即可进入多窗口模式。
退出多窗口模式:
1)再次长按Overview。
2)将屏幕中央的分割线向屏幕任意一个方向拖动到底。
(一)多窗口模式下的生命周期
多窗口模式并不会改变活动原有的生命周期,只会将用户最近交互的活动设置为运行状态,将多窗口模式下另外一个可见活动设置为暂停状态。如果这时用户又去和暂停的活动进行交互,那么该活动就会变成运行状态,之前处于运行状态的活动变成暂停状态。
进入多窗口模式后活动的大小发生了比较大的变化,此时默认会重新创建活动。
当在AndroidManifest中对活动进行配置:
……
此时不管进入多窗口模式,还是横竖屏切换,活动都不会重新创建,而是将屏幕变化的事件通知到Activity的onConfigurationChanged()方法中。
(二)禁用多窗口模式
在AndroidManifest的
android:resizeableActivity=[“true” | “false”]
其中true代表应用支持多窗口模式,false代表应用不支持多窗口模式。
(二)禁用横竖屏切换
在AndroidManifest的或
android:screenOrientation=[“portrait” | “landscape”]
其中portrait代表应用只支持竖屏,landscape代表应用只支持横屏。