每天学习一点点,成功增加一大步

Android 四大组件之一 Service 的永久驻留

Android zhanghui 265℃

为何要 Service 的永久驻留,而且 APP 在对 Service 的需求的因素有哪些:

  • 解决 APP 与远程服务器之间的通信不间断的需求。
  • 能及时接收最新的会话消息,包括更新用户的 Token 等必需的操作。
  • 希望有一个永久驻留后台,帮助解决上述需求的线程。即便 Activity 被结束了也不受影响。

上述的需求,虽然看上去这是一种【流氓】行为。但有些时候又是不得不需要的。比如微信。经常大半时间的折腾,终于搞通了,

之于 Service 是如何创建的,请看

Android 四大组件之一 Service 的创建

这里所用解决方法是通过通知广播的方式,其他方式也有,只不过这里所记录是经过验证的有效方式。

1、项目菜单中选择 Broadcast Receiver 类型文件来创建 MyReceiver 类文件。

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
            Intent i = new Intent();
            i.putExtra("MyService",intent.getStringExtra("MyService"));
            Common.Log("MyService",intent.getStringExtra("MyService"));
            i.setClass(context,MyService.class);
            context.startService(i);
        }
    }
}

这里的 Common.Log 是指(下同)

Log.i(MyApplication.TAG + " " + tag, msgStr);

2、在  AndroidManifest.xml 文件中注入,一般在 Android Studio 中通过上述操作创建 Service 文件,基本上都会自动帮助你写好一个基本的注入代码,但后面还需要自己根据实际需求去修改相关属性参数。

<application
        ……
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true"></receiver>

        ……
    </application>

2、在 MyService 的 onDestroy 方法(也就是 Service 被关闭之前回调)加上发送通知给广播重新激活的代码

@Override
    public void onDestroy() {
        Common.Log(TAG, "onDestroy 方法被调用!");
        super.onDestroy();
        Intent intent = new Intent();
        intent.setAction("restartService");
        MyService.this.sendBroadcast(intent);
    }

到这步已经基本上实现了驻留,但还可以通过 AlarmManager 来加固。

3、在 MyService 的 onStartCommand 方法(也就是 Service 被启动时调用)中写入以下代码

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Common.Log(TAG, "onStartCommand方法被调用!");
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        //这里是定时的,这里设置的是每隔两秒打印一次时间=-=,自己改
        int anHour = 2 * 1000;
        long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
        Intent i = new Intent(this, MyReceiver.class);
        i.putExtra(TAG,"aa");
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        return super.onStartCommand(intent, flags, startId);
    }

这是利用 AlarmManager 的定时功能

4、如果去验证 MyService 是否已经驻留的有效性,有两种方法,一是通过 Android 的【正在运行服务】去查看。二是借助 Timer 和 Thread 。

在 MyService 类中创建一个 Thread 线程

private class MyThread extends Thread{
        @Override
        public void run() {
// 在这里写你要真正要执行的任务
            Common.Log(TAG, new Date().toString());
        }
    }

然后基于第3步这么写:

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Common.Log(TAG, "onStartCommand方法被调用!");
        //这里开辟一条线程,用来执行具体的逻辑操作:
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
//                Common.Log(TAG, new Date().toString());
                new MyThread().start();
            }
        },0,2000);
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
       ……
    }

调试后观察 log 的变化,这样更加直观。

转载请注明:隨習筆記 » Android 四大组件之一 Service 的永久驻留

喜欢 (1)