2013-03-22 93 views
2

時工作,我有一個處理器和一個可運行,可運行的帖子敬酒屏幕每5秒,這裏是代碼:刪除處理程序回調停止離開和返回到活動

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); 
    } 
}; 

在同一活動我可以通過按下按鈕殺,調用此刪除回調:

handler.removeCallbacks(runnable); 

當上述被稱爲麪包停止顯示,因此所有已經很不錯了。當我離開我的活動轉到另一個活動時,這些吐司消息不斷顯示,這是我想要的,但是當我回到創建runnable的第一個活動並按下kill按鈕時,它不會刪除可運行的。離開和回來時,我不能再移除可運行的程序。

我試過使用幾乎所有的例子,我看過使用處理程序和runnables所以沒有什麼幫助我弄清楚這一點。

難道是當我離開我的活動並返回它創建新的runnable和處理程序對象?如果是這樣,爲什麼最初的runnable繼續運行?

回答

1

您需要實現一個在後臺運行的服務, 然後在按下按鈕時終止服務。這是你可以實現這個最簡單的方法。

+1

你能提供一個這樣的例子,我研究它,當我看了你的答案,但我不確定你的意思是什麼。謝謝! – deucalion0 2013-03-22 18:17:04

+0

我創建了一個處理我的處理程序的類,感謝這個想法! – deucalion0 2013-03-22 23:52:13

1

嘗試以下操作它使用每一個顯示你Toast每5秒的定時器類 從你的類開始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(); 

        } 
      } 
+0

我現在就試試這個,感謝您的額外幫助! – deucalion0 2013-03-23 06:48:38

+0

@ deucalioan0試試這個,如果存在問題回覆我你的logcat – 2013-03-23 11:48:04

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. 



    } 
} 

現在,在您的活動,有一類級變量保持一個參考:

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 
+0

我見過這種存儲狀態的方法以前用過,我想通過Glide框架IIRC。在我的情況下,它真的很煩人,因爲它與我的片段堆棧混淆,我需要完全控制它。考慮到這一點,在採用這種方法之前,我會考慮三次。 – 2016-10-13 12:17:10