Как выполнить асинхронную задачу повторно после фиксированных временных интервалов
Как сделать асинхронную задачу повторно выполнить через некоторый интервал времени, как таймер...На самом деле я разрабатываю приложение, которое будет автоматически загружать все последние непрочитанные приветствия с сервера, и для этого мне нужно проверить наличие обновлений с сервера через определенные промежутки времени....Я знаю, что это можно легко сделать с помощью таймера, но я хочу использовать асинхронную задачу, которая, по моему мнению, более эффективна для приложений android.
5 ответов:
public void callAsynchronousTask() { final Handler handler = new Handler(); Timer timer = new Timer(); TimerTask doAsynchronousTask = new TimerTask() { @Override public void run() { handler.post(new Runnable() { public void run() { try { PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask(); // PerformBackgroundTask this class is the class that extends AsynchTask performBackgroundTask.execute(); } catch (Exception e) { // TODO Auto-generated catch block } } }); } }; timer.schedule(doAsynchronousTask, 0, 50000); //execute in every 50000 ms }
//Every 10000 ms private void doSomethingRepeatedly() { Timer timer = new Timer(); timer.scheduleAtFixedRate( new TimerTask() { public void run() { try{ new SendToServer().execute(); } catch (Exception e) { // TODO: handle exception } } }, 0, 10000); }
вы можете просто обработчик:
private int m_interval = 5000; // 5 seconds by default, can be changed later private Handle m_handler; @Override protected void onCreate(Bundle bundle) { ... m_handler = new Handler(); } Runnable m_statusChecker = new Runnable() { @Override public void run() { updateStatus(); //this function can change value of m_interval. m_handler.postDelayed(m_statusChecker, m_interval); } } void startRepeatingTask() { m_statusChecker.run(); } void stopRepeatingTask() { m_handler.removeCallback(m_statusChecker); }
но я бы рекомендовал вам проверить эту структуру:http://code.google.com/intl/de-DE/android/c2dm/ это другой подход: сервер будет уведомлять телефон, когда что-то будет готово (таким образом, сохраняя некоторую пропускную способность и производительность:))
принятый ответ проблематичен. Использование TimerTask () для активации асинхронной задачи через обработчик-плохая идея. при повороте вы должны помнить, чтобы отменить также таймер и обработчик звонков. если нет, то он будет вызывать асинхронную задачу снова и снова на каждом повороте. Это приведет к тому, что приложение взорвет сервер (если это запрос rest http get) вместо времени X - в конечном итоге вызовы будут экземпляром много вызовов в каждую секунду. (потому что там будет много таймеров по количество оборотов экрана). Это может раздавить приложение, если активность и задача, выполняемая в фоновом потоке, являются тяжелыми. если вы используете таймер, то сделайте его классом memebr и отмените его onStop ():
TimerTask mDoAsynchronousTask; @Override public void onStop(){ super.onStop(); mDoAsynchronousTask.cancel(); mHandler.removeCallbacks(null); ... } public void callAsynchronousTask(final boolean stopTimer) { Timer timer = new Timer(); mDoAsynchronousTask = new TimerTask() { @Override public void run() { mHandler.post(new Runnable() { ...
вместо этого попытайтесь избежать асинхронной задачи, и если вы должны затем использовать службу планировщика для запуска асинхронной задачи. или класс приложения, такие как в этой Ницце идея: https://fattybeagle.com/2011/02/15/android-asynctasks-during-a-screen-rotation-part-ii/
или используйте простой обработчик (без таймера, просто используйте postDelayed), а также хорошая практика заключается в вызове отмены асинхронной задачи onStop (). этот код отлично работает с помощью postDelayed:
public class MainActivity extends AppCompatActivity { MyAsync myAsync = new MyAsync(); private final Handler mSendSSLMessageHandler = new Handler(); private final Runnable mSendSSLRunnable = new Runnable(){ .. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { mSendSSLMessageHandler.post(mSendSSLRunnable); }else .. @Override public void onStop(){ super.onStop(); if ( progressDialog!=null && progressDialog.isShowing() ){ progressDialog.dismiss(); } mSendSSLMessageHandler.removeCallbacks(mSendSSLRunnable); myAsync.cancel(false); } private final Runnable mSendSSLRunnable = new Runnable(){ @Override public void run(){ try { myAsync = new MyAsync(); myAsync.execute(); } catch (Exception e) { // TODO Auto-generated catch block } mSendSSLMessageHandler.postDelayed(mSendSSLRunnable, 5000); } }; class MyAsync extends AsyncTask<Void, Void, String> { boolean running = true; @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = ProgressDialog.show (MainActivity.this, "downloading", "please wait"); } @Override protected String doInBackground(Void... voids) { if (!running) { return null; } String result = null; try{ URL url = new URL("http://192..."); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream (urlConnection.getInputStream()); result = inputStreamToString(in); }catch(Exception e){ e.printStackTrace(); } return result; } @Override protected void onCancelled() { boolean running = false; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); progressDialog.dismiss(); try { .. } catch (JSONException e) { textView.append("json is invalid"); e.printStackTrace(); } } }