Android中的后台程序优化

(1)后台运行需求

    推送消息/广告
    播放音乐
    数据同步/文件传输
    用户活动跟踪、
    定时任务/闹钟
    内容提供者

(2)实现自动后台运行

    Stikcy Service

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY; // START_REDELIVER_INTENT;
    }

    静态注册BroadcastReceiver监听系统级事件

(3)禁用无用组件

/**
 * 监听系统事件的receiver
 */
public class AutoStartReceiver extends BroadcastReceiver {
    public AutoStartReceiver() {
    }

    /**
     * 在不需要一个receiver时,可使用该接口disable掉,
     * 这样当匹配IntentFilter的事件发生时,就不会再启动该控件了
     * @param context
     */
    public static void disable(Context context) {
        ComponentName receiver = new ComponentName(context, AutoStartReceiver.class);

        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("Receiver", intent.getAction());
        context.startService(new Intent(context, StickyService.class));
    }
}
        <receiver
            android:name=".AutoStartReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.AIRPLANE_MODE"/>
            </intent-filter>
        </receiver>

(4)定时任务

    Timer
    Handler.postDelayed
    AlarmManager(使用硬件时钟)        
public class AlarmReceiver extends BroadcastReceiver {
    public AlarmReceiver() {
    }

    /**
     * 启动一个一次性闹钟
     * 即使被kill掉也可以发生
     * @param context
     */
    public static void startOneTimeAlarm(Context context) {
        Intent intent = new Intent(context, AlarmReceiver.class);
        intent.setAction("action.startOneTimeAlarm");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, pendingIntent);
        Log.i("alarm", "start");
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("alarm", intent.getAction());

        // 再启动一个
        // 一般情况下并不需要这么做循环,使用setRepeating即可。
        // 但如果启动的闹钟要求精确时间,那么只能这么做,因为setRepeating不提供精确闹钟选项
        startOneTimeAlarm(context);
    }
}

(5)JobScheduler

    对执行时机无需精确控制
    需要特定情况满足才执行
    只能动态注册  
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobManager {

    public static void schedule(Context context) {
        ComponentName cn = new ComponentName(context, TestJobService.class);
        JobInfo.Builder jb = new JobInfo.Builder(1, cn);
        jb.setPeriodic(5000);
        jb.setRequiresCharging(true);

        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        int code = js.schedule(jb.build());
        Log.i("Job", "schedule job result: " + code);
    }

}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class TestJobService extends JobService {

    public TestJobService() {
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        Log.i("TJS", "real start job, id: " + params.getJobId());
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.i("TJS", "job stopped");
        return false;
    }
}
        <service
            android:name=".TestJobService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_JOB_SERVICE">
        </service>

(6)WakeLock

    private void backgroundTask() {
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP, "StickyService");

        wakeLock.acquire();

        try {
            Thread.sleep(30 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            wakeLock.release();
        }
    }

(7)监控电池状态

public class BatteryReceiver extends BroadcastReceiver {
    public BatteryReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_BATTERY_LOW.equals(action)) {
            Log.i("Battery", "battery low");
        } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
            Log.i("Battery", "battery ok");
        } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
            Log.i("Battery", "battery level is: " + level);
        }
    }
}
        <receiver
            android:name=".BatteryReceiver"
            android:enabled="true"
            android:exported="true">
        </receiver>
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        filter.addAction(Intent.ACTION_BATTERY_LOW);
        filter.addAction(Intent.ACTION_BATTERY_OKAY);
        registerReceiver(receiver, filter);

(8)Doze
6.0引入的打盹模式
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值