2016-03-27 7 views
1

私はAsyncTaskを1分以上実行している間にタイムアウトを作成しようとしています。タイムアップした場合は、通知で終了する必要があります。AsyncTask実行のタイムアウトを設定するには?

これは私のコードです:

private class GetLongLat extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     longlatDialog = new ProgressDialog(MainActivity.this); 
     longlatDialog.setMessage("Fetching Data. Please wait.."); 
     longlatDialog.setCancelable(false); 
     longlatDialog.show(); 

    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     GPSTracker gpsTracker; 

     //This is the timer to set time out 
     Timer timer = new Timer(); 
     timer.schedule(new TaskKiller(this), 3000); 
     timer.cancel(); 

     do{ 
      gpsTracker = new GPSTracker(MainActivity.this); 
      gpsTracker.getLocation(); 

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0")); 

     return null; 
    } 

    protected void onCancelled() { 
    // do something, inform user etc. 
     Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
     System.exit(1); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     if (longlatDialog.isShowing()) 
      longlatDialog.dismiss(); 
    } 

} 

そして、これは時間を設定するにはdoInBackgroundで呼び出されるクラスです。

class TaskKiller extends TimerTask { 
private AsyncTask<?, ?, ?> mTask; 

    public TaskKiller(AsyncTask<?, ?, ?> task) { 
    this.mTask = task; 
    } 

    public void run() { 
    mTask.cancel(true); 
    } 
} 

しかし、コードを実行すると何も起こりません。私は進捗ダイアログが常に非常に長い時間を実行することを意味します。

GetLongLat n = new GetLongLat(); 
n.execute(); 
try { 

    n.get(3000, TimeUnit.MILLISECONDS); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (ExecutionException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (TimeoutException e) { 
    // TODO Auto-generated catch block 
    Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
    System.exit(1); 
} 

しかし、また、動作しません:

EDIT は、私はこのようなGetLongLat何かを呼び出すために私のコードを編集しています。

+0

ます。http書く://のstackoverflowを。com/questions/7882739/android-setting-a-timeout-for-asynctask – Manifest

答えて

1

私はあなたがAsyncTask.getを(使用することができると思う)

GetLongLat n = new GetLongLat(); 
n.get(30000, TimeUnit.MILLISECONDS); 

あなたは別のスレッドでn.getを使用する必要があります。..

編集:1つの以上の異なる方法が、効率的ではありません。 、

GetLongLat n = new GetLongLat(); 
n.execute(); 
Handler handler = new Handler(); 
handler.postDelayed(new Runnable() 
{ 
    @Override 
    public void run() { 
     if (n.getStatus() == AsyncTask.Status.RUNNING) 
      n.cancel(true); 
    } 
}, 30000); 
+0

私はあなたの答えに基づいてコードを編集しています。私は知らないが動作しません。 @サラン –

+0

@SamsulArifinあなたが直面しているエラー/問題は何ですか? – sharan

+0

とn.getを実行する別のスレッドを作成してメインスレッドでこれを実行しないでください... – sharan

0

は、なぜあなたはタイマーをキャンセルしていますか? schedule()に電話した直後ですか?

timer.cancel();を削除する必要がありますタイマー、すべてのスケジュールされたタスクをキャンセルします。キャンセル()のdocsを確認してください

0

多くの方法でこの動作を実現できます。

は、ここであなたはそれを開始した後、タイマーをキャンセルしているCountDownTimer

// Start your AsyncTask 
private YourAsyncTask mTask = new YourAsyncTask().execute(); 

// Run a timer after you started the AsyncTask 
new CountDownTimer(60000, 1000) { 

    public void onTick(long millisUntilFinished) { 
     // Do nothing 
    } 

    public void onFinish() { 
     mTask.cancel(true); 
    } 

}.start(); 

使用例です。あなたもこのようにすることができます。しかし、このタイプのビジー・ウェイティングはまったくお勧めできません。

@Override 
protected Void doInBackground(Void... arg0) { 

    GPSTracker gpsTracker; 

    //This is the timer to set time out 
    new CountDownTimer(60000, 1000) { 

     public void onTick(long millisUntilFinished) { 
      // Do nothing 
     } 

     public void onFinish() { 
      // Set latitude to zero to finish the while loop outside. 
      // gpsTracker.latitude = "0.0"; // Something like this 
     } 

    }.start(); 

    do{ 
     gpsTracker = new GPSTracker(MainActivity.this); 
     gpsTracker.getLocation(); 

    }while(!String.valueOf(gpsTracker.latitude).equals("0.0")); 

    return null; 
} 
1

別のアプローチがあります。 doInBackgroundメソッドでは、System.currentTimeMillisを使用して、1分が経過したかどうかを確認できます。

protected Void doInBackground(Void... arg0) { 

     GPSTracker gpsTracker; 

     long startTime = System.currentTimeMillis(); 

     do{ 
      gpsTracker = new GPSTracker(MainActivity.this); 
      gpsTracker.getLocation(); 

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0") 
       && ((System.currentTimeMillis() - startTime) <= 60000);//60000 millisecond = 1 minute 

     return null; 
} 

`

+0

次に、タイムアウトするとアプリを終了するコードですか? –

+0

タイムアウトに達すると、ループは自動的に終了し、 'doInBackground' methdから' null 'が返されます。その後、 'onPostExecute'が呼び出され、あなたのコードをそこに置くことができます。 –

+0

私もあなたのコードを試しています。そして私はより効率的で効果的だと思います。しかし、私はまだ時間切れとonPostExeuteの間でチェックするのが混乱します。アイデアはありますか? –

0

ただ、このようなあなたのコードを変更して、非同期タスクがキャンセルかなっているかどうかを確認してください。

  GetLongLat getLongLatAsync = new GetLongLat(); 
      getLongLatAsync.execute(); 
      try { 
      Handler handler = new Handler(); 
      /** 1st method **/ 
      handler.postDelayed(new Runnable() 
      { 
       @Override 
       public void run() { 
       if (getLongLatAsync.getStatus() == AsyncTask.Status.RUNNING) 
        getLongLatAsync.cancel(true); 
       } 
       }, 3000); //3 Seconds 
    /** 1st method ends **/ 
    /** second method */ 
      handler.post(new Runnable() 
      { 
       @Override 
       public void run() { 
     getLongLatAsync.get(3000, TimeUnit.MILLISECONDS);//You should run it in seperated thread or else it will block ui thread. 
    } 
    }); 
/** Second method ends**/ 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (TimeoutException e) { 
       // TODO Auto-generated catch block 
       Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show(); 
      } 

とonCancelld方法であなたのロジック

@Override 
protected void onCancelled() { 
Log.d(TAG,"Asynctask has been cancelled."); 
} 
+0

私はあなたのコードを試しています。それのすべて。次に、同じ結果。私が上で尋ねたポイントは、ユーザーがGPSをオンにした後、自動的にロングとラージをロードすることです。しかし、時には、ユーザーが遅いインターネット接続を持っているので、ユーザーが1分後に長いlatを読み込めない場合。アプリは終了します。 –

+0

私たちのために働いているので、あなたが別の何かをしていない限り、上記の方法は動作するはずです! –

+0

あなたの答えをありがとう。私は別の方法で見つけられました。これはhttp://stackoverflow.com/questions/7882739/android-setting-a-timeout-for-an-asynctask 完全に動作します。しかし、あなたのコードは別の方法でも動作します。再度ありがとう –

関連する問題