[英]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_STICKY
在onStartCommand()
return START_STICKY
则Android系统可以重新启动服务。
与Android中的Lollipop相比,它在所有较低版本上均能完美运行。
无需CountDownTimer。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.