Android小技巧

1.使用Intent传递对象

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

Serializable是序列化的意思,标示将一个对象转换成可存储或可传输的状态,序列化后的对象可以在网络上进行传输也可以存储到本地,只需要让一个类去实现Serializable这个接口。可通过getSerialzableExtra()方法来获取通过参数传递过来的序列化对象。

Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型。首先实现Parcelable接口,重写describeContents()和writeToParcel()两个方法,describeContents()方法直接返回0,而writeToParcel()方法中调用writexxx()将类中字段一一写出,创建一个CREATOR常量,创建Parcelable.Creator接口的一个实现,重写createFromParcel()和newArray()两个方法,在createFromParcel()方法中读取写出的字段,并创建一个对象进行返回,newArray()方法中new出一个实例的数组,并使用方法中传入的size作为数组的大小就可以。可通过getParcelableExtra()方法来获取传递过来的对象。

Serializable的方式较为简单,由于会把整个对象进行序列化,效率会比Parcelabel方式低一些,推荐使用Parcelable的方式来实现Intent传递对象的功能。

2.创建定时任务

Android中的定时任务一般有两种实现方式,一种是使用Java API里提供的Timer类,一种是使用Android的Alarm机制。Timer又一个明显的短板,它不太适合那些需要长期在后台运行的定时任务,为了让电池更加耐用,每种手机都有自己的休眠策略,Android手机在长时间不操作的情况下自动让CPU进入睡眠状态,这就有可能导致Timer中的定时任务无法正常运行。而Alarm则具有唤醒CPU的功能,它可以保证在大多数情况下需要执行定时任务的时候CPU都能正常工作。

设定一个任务10s后执行:

 AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        long triggerAtTime = SystemClock.elapsedRealtime() + 10 * 1000;
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,peddingIntent);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        long triggerAtTime = System.currentTimeMillis() + 10 * 1000;
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,peddingIntent);

第一个参数用于指定AlarmManager的工作类型,有四种类型:

AlarmManager.ELAPSED_REALTIME :表示让定时任务的触发时间从系统开机开始算起,但不会唤醒CPU。

AlarmManager.ELAPSED_REALTIME_WAKEUP:表示让定时任务的触发时间从系统开机开始算起,但会唤醒CPU。

AlarmManager.RTC:表示让定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒CPU。

AlarmManager.RTC_WAKEUP:表示让定时任务的触发时间从1970年1月1日0点开始算起,但会唤醒CPU。

SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数,使用System.currentTimeMills()方法可以获取1970年1月1日0点至今所经历时间的毫秒数。

第二个参数是定时任务触发的时间,以毫秒为单位,如果第一个参数使用的是ELAPSED_REALTIME或ELAPSED_REALTIME_WAKEUP,这里传入开机至今的时间再加上延迟执行的时间。如果第一个参数使用的是RTC或者RTC_WAKEUP,这里传入的是1970年1月1日0点至今的时间再加上延迟执行的时间。

第三个参数是一个PendingIntent,我们一般用getService()方法或者getBroadcast()方法来获取一个能够执行服务或广播的PendingIntent,这样当定时任务被触发的时候,服务的onStartCommand()方法或广播接收器的onReceive()方法就可以执行。

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("test","do something");
            }
        }).start();
        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        long triggerAtTime = SystemClock.elapsedRealtime() + 3 * 1000;
        Intent i = new Intent(this,MyService.class);
        PendingIntent pi = PendingIntent.getService(this,0,i,0);
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);
        return super.onStartCommand(intent, flags, startId);
    }
Android4.4后,Alarm任务的触发时间会变得不准确,可用AlarmManager的setExact()方法来替代set()方法。


3.Doze模式

Android6.0系统中,谷歌加入了一个全新的Doze模式,可以极大幅度地延长电池的寿命。如果用户的设备是Android6.0或以上系统该设备未插电源,处于静止状态,且屏幕关闭了一段时间后,就会进入Doze模式,在Doze模式下,系统化会对CPU,网络,Alarm等活动进行限制,从而延长电池的使用寿命。

4.多窗口编程模式

Android7.0系统中引入多窗口模式,允许我们在同一个屏幕中同时打开两个应用程序。

5.Lambda表达式

Java8中的新特性Lambda表达式,本质上是一种匿名方法,它既没有方法名,也没有访问修饰符和返回值类型,用它来编写代码将会更加简洁和易读。凡是只有一个待实现方法的接口,都可以使用Lambda表达式的写法。

// Java 8之前:
new Thread(new Runnable() {
@Override
public void run() {
        System.out.println("Before Java8, too much code for too little to do");
        }
        }).start();
//Java 8方式:
        new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值