2016-07-16 58 views
2

我想實現這個功能: 當用戶點擊按鈕啓動任務,並在5分鐘後發送一個文件到Dropbox,但如果用戶點擊另一次按鈕,先例任務中止和新任務(5分鐘)開始。長延時AsyncTask和重啓任務

我編寫了上傳文件到Dropbox的代碼,但從未用如此長的時間(5分鐘)使用任務編寫代碼。 這怎麼辦?

- 編輯 -

感謝@ xdevs23,我已經實現了最終代碼

public void onSendOrder() { 

     try { 
      mHandler.removeCallbacks(postRunnable); // stop current wait 
     } catch(Exception ex) { 
      // Just if the above fails (might be first time) 
      ex.printStackTrace(); 
     } 
     int minutes = 5; 
     mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */); 
... 
... 
... 

private Runnable postRunnable = new Runnable() { 
     @Override 
     public void run() { 
      Thread myThread = new Thread(myRunnable); 
      myThread.start(); 
     } 
    }; 


    private Runnable myRunnable = new Runnable() { 
      @Override 
      public void run() { 
       // your code 
       int cloud = GetPreferenceCloud(); 
       if(cloud > 0){ 
        ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 
        final File bckDatabase = BackupDatabase(); 

        if (networkInfo != null && networkInfo.isConnected() && bckDatabase != null) { 

        runOnUiThread(new Runnable() { 
         public void run() { 
          // call your asynctask here 
          new UploadOnCloud(MainActivity.this, 
            PreferenceConstants.DB_DATABASE_STORE_CLOUD, 
            PreferenceConstants.FILE_DIR_CLOUD, 
            bckDatabase, 
            mUListener, 
            cloud).execute(); 
         } 
        }); 

       } else { 
         Toast.makeText(getContext(),getContext().getResources().getString(R.string.send_msg13), Toast.LENGTH_SHORT).show(); 
        } 
       } 
      } 
     }; 

*編輯。 V2 *

爲了實現在狀態條上的倒計時,我實現了這一點:

修改onSend功能:

public void onSendOrder() { 

     try { 
      mHandler.removeCallbacks(postRunnable); // stop current wait 
     } catch(Exception ex) { 
      // Just if the above fails (might be first time) 
      ex.printStackTrace(); 
     } 
     minute = 3600; 
     //mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */); 
     mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */); 

.... ....

file menu.xml

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <item android:id="@+id/break_timer" 
      android:title="00:00" 
      app:showAsAction="always" 
      app:actionViewClass="android.widget.TextView" /> 
    <item 
     android:id="@+id/action_refresh" 
     android:title="@string/action_refresh" 
     app:showAsAction="ifRoom" 
     android:icon="@drawable/ic_action_autorenew"/> 
</menu> 

修改onC reateOptionsMenu

public boolean onCreateOptionsMenu(Menu menu) { 

     getMenuInflater().inflate(R.menu.main, menu); 
     MenuItem timerItem = menu.findItem(R.id.break_timer); 
     timerText = (TextView) MenuItemCompat.getActionView(timerItem); 
     timerText.setPadding(10, 0, 10, 0); //Or something like that... 

     return super.onCreateOptionsMenu(menu); 
    } 


private int minute; 
    private Runnable postRunnable = new Runnable() { 
     @Override 
     public void run() { 
      if(minute >= 0){ 
       minute--; 
       mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */); 
       timerText.setText(secondsToString(minute)); 
      }else { 
       Thread myThread = new Thread(myRunnable); 
       myThread.start(); 
      } 
     } 
    }; 

回答

2

而不是使用AsyncTask的,你可以使用Thread S和Runnable秒。

創建Runnable在您的代碼,要在後臺運行,位於:

Runnable myRunnable = new Runnable() { 
    @Override 
    public void run() { 
     // your code 
    } 
} 

創建Thread

private Thread myThread; 

請確保您有一個處理器上創建主線程。 爲了達到最佳效果,將它添加到您的onCreate()方法:

private Handler mHandler; 

@Override 
public void onCreate() { 
    // ... 
    mHandler = new Handler(); 
    // ... 
} 

您需要導入android.os.Handler

聲明可運行在您上傳的代碼是:

private Runnable postRunnable = new Runnable() { 
    @Override 
    public void run() { 
     Thread myThread = new Thread(myRunnable); 
     myThread.start(); 
    } 
} 

當用戶點擊該按鈕現在做如下:

try { 
    mHandler.removeCallbacks(postRunnable); // stop current wait 
} catch(Exception ex) { 
    // Just if the above fails (might be first time) 
} 
int minutes = 5; 
mHandler.postDelayed(postRunnable, minutes * 60 * 1000 /* 5 minutes in milliseconds */); 

就是這樣。

說明:

當用戶點擊該按鈕時,它會等待(不會阻塞UI)爲5秒,然後它會運行內部postRunnable的代碼,其中在開始一個新的線程背景,它將運行myRunnable中的代碼。

編輯更新通知

private Handler mHandler; 
private int minutes = 5; 
private Runnable updateRunnable = new Runnable() { 
    @Override 
    public void run() { 
     if(minutes > 0) { 
      String notifContent = "" + minutes + " remaining."; 
      // Create your notification (there are several guides which show you how to do this), use notifContent as title or text or whatsoever 
      minutes--; 
      mHandler.postDelayed(updateRunnable, 60 * 1000); 
     } else { 
      // Remove your notification 
     } 
    } 
}; 

開始倒數​​:

mHandler.post(updateRunnable); 
+0

不客氣。其他問題到底是什麼? – xdevs23

+0

我想在狀態欄中實現一個減計數器,以顯示在將文件發送到服務器之前剩餘的分鐘數/秒... –

+0

您可以創建一個帶有runnable的線程,該線程將每分鐘運行**和只要runnable運行,就倒計時int int minutes變量。在可運行時,您可以顯示通知,例如,使用當前的'int minutes'值。 – xdevs23

相關問題