重复的后台任务Android - Handler vs AlarmManager

时间:2016-02-11 10:49:15

标签: java android multithreading android-activity android-handler

我正在研究用于研究目的的申请。我们想要跟踪手机上的一些用户活动:如果某些操作可以通过广播接收器轻松删除,我们还需要检查当前正在运行的应用程序。 此应用程序仅适用于运行Android 5.0或更低版本的Android设备。

我的问题是我在一个处理程序中发布了一个Runnable Obj,Runnable在HALF_SECOND之后再次在处理程序中发布(详见代码)。在runnable中,我获取信息并将它们发送到IntentService以执行工作。

一切正常:app在启动时启动,处理程序和runnable在后台完成工作除非我打开主Activity。 该应用程序能够持续数天,但如果我打开主Activity,然后通过滑动从“最近的打开活动”关闭它,或从内存任务管理器,处理程序和可运行停止,即使它们未被调用/由活动访问(他们在单独的服务中)。 此外,并不总是调用onDestroy(活动或服务)。 在线阅读我明白刷卡或任务管理器会从内存中删除应用程序,因此并不总是调用onDestory。

我想要实现的是在主活动关闭后立即重新启动处理程序。

我试过的是对活动的onPause方法进行一些检查,如果再次调用onStart,请确保删除此检查(例如,应用程序从垂直布局切换到水平布局,或者按下主页按钮然后app再次打开)。还实现了一种方法,使处理程序向广播接收器发送“ImAlive”意图,如果意图在倒计时结束之前没有到达,则应重新启动启动处理程序的服务。不幸的是,一旦主要活动停止存在,即使广播也会自动取消注册和销毁。

我的问题是,有没有办法创建能够在活动关闭时重启我的处理程序的东西?或者是否有其他模式可以帮助我解决我想要达到的目标?因为我每半秒轮询一次数据,所以我最好使用处理程序,因为Timer会将小间隔增加到更大的间隔,而AlarmManager对于非常小的间隔来说不够精确。

我想要实现的是与Facebook,Instagram,Whatsapp,Telegram应用程序类似的东西,它总是在内存中,即使你强行终止它们,几秒钟后再回到那里......怎么样? / p>

由于对数据的持续轮询,我们对电池问题不感兴趣。至于研究目的,我们不介意我们测试的手机是连续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");


    }
}

非常感谢任何帮助,如果您需要有关代码的更多信息,我会更新帖子。 谢谢!

1 个答案:

答案 0 :(得分:0)

  • 如果LocalDate date=LocalDate.now(); System.out.println(date.getDayOfWeek());//prints THURSDAY System.out.println(date.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US) ); //prints Thu java.time.DayOfWeek is a enum which returns the singleton instance for the day-of-week of the weekday of the date. 内有return START_STICKY,Android系统可以重新启动该服务。

  • 它完全适用于所有比Android中的Lollipop低版本。

  • 不需要CountDownTimer。