web-dev-qa-db-ja.com

Android-postDelayed()呼び出しを使用して定期的にメソッドを実行する

Androidアプリで、1秒ごとに実行するネットワークアクティビティ(データの送信)を開始したい状況があります。これを次のように達成します。

onCreate()には次のコードがあります:

tv = new TextView(this);
tv.postDelayed(sendData, 1000);

sendData()関数:

   Handler handler = new Handler();
   private Runnable sendData=new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..
            handler.removeCallbacks(sendData);
            handler.postDelayed(sendData, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

問題は次のようになります。ユーザーが戻るボタンを押してアプリが表示される(UIが消える)場合、sendData()関数が実行されますが、これは私が望むものです。ユーザーがアプリを再起動すると、onCreate()が再度呼び出され、sendData()が1秒間に2回呼び出されます。それはそのように続きます。ユーザーが出て再起動するたびに、毎秒もう1つsendData()が発生します。

私は何を間違えていますか? new Handler()作成の問題ですか?これを処理する最良の方法は何ですか?ユーザーがアプリ(フォームアプリケーションマネージャー)を終了するまで、1秒間に1つのsendData()呼び出しが必要です。

41
zolio

サービスを作成し、onCreate()にロジックを入れてみませんか。この場合、戻るボタンを押してもサービスは実行を続けます。そして、アプリケーションに入ると、onCreate()を再度呼び出しません。むしろ、onStart()を呼び出します

27
Vipul Shah
final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        //Do something after 100ms
        Toast.makeText(c, "check", Toast.LENGTH_SHORT).show();  
        handler.postDelayed(this, 2000);
      }
    }, 1500);
96
Saad Asad

おそらく、これを達成するためにアクティビティのライフサイクルメソッドが含まれます。

Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      handler.post(sendData);
}

@Override
protected void onDestroy() {
      super.onDestroy();
      handler.removeCallbacks(sendData);
}


private final Runnable sendData = new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..


            handler.postDelayed(this, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

このアプローチでは、アクティビティでback-keyを押すか、finish();を呼び出すと、postDelayedの呼び出しも停止します。

27
waqaslam

このようにコードを簡素化できます。

Javaの場合:

new Handler().postDelayed (() -> {
    //your code here
}, 1000);

コトリンで:

Handler().postDelayed({
   //your code here
}, 1000)
12
Varun Chandran

あなたが同じアクティビティをしているときに1秒ごとにハンドラが実行されるコードの下で、私の側での動作を確認してください

 HandlerThread handlerThread = new HandlerThread("HandlerThread");
                handlerThread.start();
                handler = new Handler(handlerThread.getLooper());
                runnable = new Runnable()
                {
                    @Override
                    public void run()
                    {

                            handler.postDelayed(this, 1000);
                        }
                };
                handler.postDelayed(runnable, 1000);
2
sharma_kunal
Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what==0){
            // do stuff
            h.removeMessages(0);  // clear the handler for those messages with what = 0
            h.sendEmptyMessageDelayed(0, 2000); 
        }
    }
};


 h.sendEmptyMessage(0);  
1
Dan Alboteanu

複数のインスタンスのように聞こえるので、さまざまなアクティビティフラグを試すことができると思います。

「singleTop」「singleTask」「singleInstance」

私が試すものは、マニフェスト内で定義できます。

http://developer.Android.com/guide/topics/manifest/activity-element.html

0
Tony

Manifest.xmlでアクティビティを起動するにはandrid:allowRetainTaskState = "true"を設定する必要があります。このアクティビティが起動アクティビティでない場合。このアクティビティでAndroid:launchMode = "singleTask"を設定する必要があります

0
Folee