我有一个处理程序和一个runnable,runnable每5秒向屏幕发布一次toast,这是代码:
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "DISPLAY MESSAGE" + walking, Toast.LENGTH_SHORT).show();
handler.postDelayed(runnable, 5000);
}
};
在同一个活动中,我可以通过按下kill按钮来删除回调,调用它:
handler.removeCallbacks(runnable);
当上面这个叫做Toast停止显示所以到目前为止一切都很好。当我离开我的活动去另一个活动时,toast消息会一直显示,这就是我想要的,但当我回到创建runnable的第一个活动并按下kill按钮时,它不会删除runnable。离开和回来时我无法再移除可运行的东西。
我尝试过使用几乎所有我在SO上使用Handler和runnables的例子,没有任何东西可以帮助我解决这个问题。
当我离开我的Activity并返回它时会创建新的runnable和handler对象吗?如果是这样,为什么初始runnable会继续运行?
答案 0 :(得分:2)
在活动中保留长期参考资料是一种糟糕的形式。即使您旋转手机,它们也会轻松地经常被破坏和重新创建!发生的事情是重新创建Activity时,你怀疑有一个新的Runnable和Handler对象。
为了避免使用服务来解决这个问题,我所做的就是创建一个片段...让我们称之为StateFragment。
为此片段提供无视图,因此对用户不可见。它仅用于存储变量。创建活动后,如果活动尚未存在,请将其添加到活动中。最后,在Fragment类本身中,在onCreate中,setRetainInstance为true。
我承认这有点像黑客,但它是一种非常方便的方法,可以在创建和销毁活动时保留流程中的变量。在这种情况下,当Activity被销毁并重新创建时,片段可能会被保留,除非它已经在后台停留一段时间并由GC清理。下面是一些代码:
public class StateFragment extends Fragment{
//add some variables here
//these will not last long time!
Handler handler;
Runnable runnable;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
setRetainInstance(true); //<--this is the important part!
Handler = new Handler... etc.
}
}
现在在您的Activity中,有一个类级变量来保留引用:
public Class MainActivity extends FragmentActivity {
StateFragment sf;
然后在你的“onCreate”中你需要检查它是否存在,否则附上它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sf=(StateFragment) getFragmentManager().findFragmentByTag("storage");
if (sf==null)
{
sf=new StateFragment();
getFragmentManager().beginTransaction().add(sf, "storage").commit();
}
总的来说,我发现活动的波动性是一个巨大的痛苦,并且拥有更持久的存储通常是一个很大的好处。现在您可以轻松地将Runnable引用为
sf.runnable
答案 1 :(得分:1)
您需要实现在后台运行的服务, 然后在按下按钮时终止服务。这是实现这一目标的最简单方法。
答案 2 :(得分:1)
尝试以下操作,每隔5秒显示一次Toast
,就会使用一个计时器类
从你的类启动backhelper服务类:
public class BackHelper extends Service {
@Override
public void onCreate()
{
Log.i(TAG, "Service onCreate");
super.onCreate();
Timer timer = new Timer();
TimerTask updateProfile = new BackHelper(sock.this);
timer.scheduleAtFixedRate(updateProfile, 0, 5000);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.i(TAG, "Service onDestroy");
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i(TAG, "Service onstart");
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.i(TAG, "Service onBind");
return null;
}
public class sock extends TimerTask
{
@Override
public void run()
{
Toast.makeText(getBaseContext(), "DISPLAY MESSAGE" + walking, Toast.LENGTH_SHORT).show();
}
}