繁体   English   中英

重复执行的后台任务Android-处理程序与AlarmManager

[英]Recurring background task Android - Handler vs AlarmManager

我正在研究用于研究目的的应用程序。 我们希望跟踪电话上的某些用户活动:如果某些行为可以通过广播接收器轻松确定,我们还希望检查当前正在运行的应用程序。 此应用程序仅适用于运行android 5.0或更低版本的Android设备。

我的问题是我在处理程序中发布了Runnable Obj,在HALF_SECOND之后,Runnable再次在处理程序中本身发布了(请参阅代码以获取详细信息)。 在可运行状态下,我获取信息并将其发送到IntentService以执行工作。

一切正常:应用程序在启动时启动,处理程序和可运行程序在后台运行其工作,除非我打开主活动。 该应用程序可以继续运行几天,但是如果我打开主活动,然后通过滑动从“最近的活动”中关闭它,或者从内存任务管理器,处理程序和可运行的停止位置将其关闭,即使它们未被调用/由活动访问(它们在单独的服务中)。 此外,并非总是调用(活动或服务的)onDestroy。 在线阅读我知道滑动或任务管理器会从内存中彻底删除该应用程序,因此并不总是调用onDestory。

我要实现的是使处理程序在主活动关闭后不久重新启动。

我尝试过的是在活动的onPause方法中添加一些检查,确保再次调用onStart时除去此检查(例如,如果应用程序从垂直布局切换为水平布局,或者如果按下主屏幕按钮然后再按下应用程序再次打开)。 还实现了一种使处理程序向广播接收器发送“ ImAlive”意图的方法,如果意图在倒计时完成之前没有到达,广播接收器应重新启动启动处理程序的服务。 不幸的是,一旦主要活动停止存在,甚至广播也将自动注销并销毁。

我的问题是,如果活动关闭,是否可以创建某种方法使我的处理程序重新启动? 还是有其他模式可以帮助我解决要实现的目标? 因为我每隔半秒轮询一次数据,所以更好地使用处理程序,因为Timer将较小的间隔增加到较大的间隔,并且AlarmManager对于非常小的间隔不够精确。

我要实现的是类似于Facebook,Instagram,Whatsapp,Telegram应用程序的内容,它们始终存在于内存中,即使您强制终止它们,几秒钟后又回到那里...如何?

由于对数据进行连续轮询,因此我们对电池问题不感兴趣。 出于研究目的,我们不介意所测试的手机连续连续2天,1天或12小时或更短。

这里的代码:OnBootService从广播接收器启动,在接收到onBootCompleted和ShutDown操作时在清单中声明,以启动和停止处理程序。

public class OnBootService extends Service{
    private static final Handler handler = new Handler();
    private final long HALF_SEC = 500;
    private RunnableTest r = null;
    private Context myContext = this;
    private final String TAG = "BootService";
    // Extras
    public static final String START = "start";
    public static final String STOP = "stop";

    @Override
    public IBinder onBind(Intent intent){
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flag, int startId){

        String action = intent.getAction();

        switch(action){
            case START: startHandler();
                break;
            case STOP: stopHandler();
                break;
        }

        return START_NOT_STICKY;
    }

    private void startHandler(){
        if(r == null){
            r = new RunnableTest();

            handler.post(r);
            Log.i(TAG, "----Handler started!");
        }

    }

    private void stopHandler(){    
        if(r != null){
            Log.i(TAG, "----calling STOP");
            handler.removeCallbacks(r);
            r = null;
        }

    }

    private class RunnableTest implements Runnable {
        private String TAG = "RunnableTest";

        public RunnableTest(){}

        @Override
        public void run(){
            handler.removeCallbacks(this);

            // Do stuff
            Intent i = new Intent(myContext, MyIntentService.class);
            i.putExtra("addStuff", myStuff);
            myContext.startService(i);

            handler.postDelayed(this, HALF_SEC);
        }

    }

活动为空:为了了解适当的活动生命周期,所有方法都被覆盖,但目前其他情况下为空。

public class MainActivity extends AppCompatActivity {
    private final String TAG = "Activity";
    private Context myContext = this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    // access a file and get stored information to show

        setContentView(R.layout.activity_main);
        Toast.makeText(getBaseContext(), "Application open successfully", Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onRestart(){
        super.onRestart();
        Log.e(TAG, "----onRestart Called");
    }

    @Override
    protected  void onStart(){
        super.onStart();
        Log.e(TAG, "----onSTART Called");
    }

    @Override
    protected  void onResume(){
        super.onResume();
        Log.e(TAG, "----onRESUME Called");

    }

    @Override
    protected  void onPause(){
        super.onPause();
        Log.e(TAG, "----onPAUSE Called");

    }

    @Override
    protected  void onStop(){
        super.onStop();
        Log.e(TAG, "----onSTOP Called");
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        Log.e(TAG, "----onDestroy Called");


    }
}

非常感谢您的帮助,如果您需要有关代码的更多信息,我将进行更新。 谢谢!

  • 如果return START_STICKYonStartCommand() return START_STICKY则Android系统可以重新启动服务。

  • 与Android中的Lollipop相比,它在所有较低版本上均能完美运行。

  • 无需CountDownTimer。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM