143

Android 2.3.3アプリケーションを開発していて、 X秒ごとにメソッドを実行する必要があります。

iOSではNSTimerを使用していますが、Androidでは何を使用すればよいかわかりません。

誰かが私にハンドラーを勧めました; 別の人が私にAlarmManagerを勧めますが、どの方法がNSTimerに適しているかわかりません。

これは私がAndroidに実装したいコードです:

timer2 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f)
    target:self
    selector:@selector(loopTask)
    userInfo:nil
    repeats:YES
];

timer1 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f)
    target:self
    selector:@selector(isFree)
    userInfo:nil
    repeats:YES
];

NSTimerのように機能するものが必要です。

何をお勧めしますか?

4

8 に答える 8

190

使用するソリューションは、関数の各実行の間に待機する必要がある時間によって異なります。

10分以上待っている場合は、を使用することをお勧めしAlarmManagerます。

// Some time when you want to run
Date when = new Date(System.currentTimeMillis());

try {
    Intent someIntent = new Intent(someContext, MyReceiver.class); // intent to be launched

    // Note: this could be getActivity if you want to launch an activity
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
        context,
        0, // id (optional)
        someIntent, // intent to launch
        PendingIntent.FLAG_CANCEL_CURRENT // PendingIntent flag
    );

    AlarmManager alarms = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE
    );

    alarms.setRepeating(
        AlarmManager.RTC_WAKEUP,
        when.getTime(),
        AlarmManager.INTERVAL_FIFTEEN_MINUTES,
        pendingIntent
    );
} catch(Exception e) {
    e.printStackTrace();
}

上記をブロードキャストしたら、を実装してIntentを受信できます。これは、アプリケーションマニフェストまたはメソッドを介して登録する必要があることに注意してください。の詳細については、公式ドキュメントを参照してください。IntentBroadcastReceivercontext.registerReceiver(receiver, intentFilter);BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent)
    {
        System.out.println("MyReceiver: here!") // Do your work here
    }
}

10分未満待っている場合は、を使用することをお勧めしHandlerます。

final Handler handler = new Handler();
final int delay = 1000; // 1000 milliseconds == 1 second

handler.postDelayed(new Runnable() {
    public void run() {
        System.out.println("myHandler: here!"); // Do your work here
        handler.postDelayed(this, delay);
    }
}, delay);
于 2012-07-11T13:49:43.543 に答える
119

毎秒タイマーを使用...

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //your method
    }
}, 0, 1000);//put here time 1000 milliseconds=1 second
于 2012-07-11T13:48:44.237 に答える
93

このコードを試して、onResume()を介して15秒ごとにハンドラーを呼び出し、onPause()を介してアクティビティが表示されていないときにハンドラーを停止してください。

Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000; //Delay for 15 seconds.  One second = 1000 milliseconds.


@Override
protected void onResume() {
   //start handler as activity become visible

    handler.postDelayed( runnable = new Runnable() {
        public void run() {
            //do something

            handler.postDelayed(runnable, delay);
        }
    }, delay);

    super.onResume();
}

// If onPause() is not included the threads will double up when you 
// reload the activity 

@Override
protected void onPause() {
    handler.removeCallbacks(runnable); //stop handler when activity not visible
    super.onPause();
}
于 2016-10-15T10:40:39.853 に答える
20

RxJavaに精通している場合は、Observable.interval()を使用できます。これは非常に便利です。

Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(new Function<Long, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(@NonNull Long aLong) throws Exception {
                    return getDataObservable(); //Where you pull your data
                }
            });

これの欠点は、データのポーリングを別の方法で設計する必要があることです。ただし、リアクティブプログラミングの方法には多くの利点があります。

  1. コールバックを介してデータを制御する代わりに、サブスクライブするデータのストリームを作成します。これにより、「データのポーリング」ロジックと「UIへのデータの入力」ロジックの問題が分離され、「データソース」コードとUIコードが混在しないようになります。
  2. RxAndroidを使用すると、わずか2行のコードでスレッドを処理できます。

    Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(...) // polling data code
          .subscribeOn(Schedulers.newThread()) // poll data on a background thread
          .observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread
          .subscribe(...); // your UI code
    

RxJavaをチェックしてください。学習曲線は高くなりますが、Androidでの非同期呼び出しの処理が非常に簡単でクリーンになります。

于 2017-07-13T06:46:35.153 に答える
9

Kotlinを使用すると、このためのジェネリック関数を作成できます。

object RepeatHelper {
    fun repeatDelayed(delay: Long, todo: () -> Unit) {
        val handler = Handler()
        handler.postDelayed(object : Runnable {
            override fun run() {
                todo()
                handler.postDelayed(this, delay)
            }
        }, delay)
    }
}

そして、使用するには、次のようにします。

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
    myRepeatedFunction()
}
于 2019-06-26T16:38:03.433 に答える
5
    new CountDownTimer(120000, 1000) {

        public void onTick(long millisUntilFinished) {
            txtcounter.setText(" " + millisUntilFinished / 1000);

        }

        public void onFinish() {

            txtcounter.setText(" TimeOut  ");
            Main2Activity.ShowPayment = false;
            EventBus.getDefault().post("go-main");

        }

    }.start();
于 2018-08-20T10:00:52.213 に答える
2

ここでは、onCreate()アクティビティでスレッドを繰り返し使用しましたが、タイマーですべてが許可されない場合がありますスレッドが解決策です

     Thread t = new Thread() {
        @Override
        public void run() {
            while (!isInterrupted()) {
                try {
                    Thread.sleep(10000);  //1000ms = 1 sec
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE);
                            Gson gson = new Gson();
                            String json = mPrefs.getString("chat_list", "");
                            GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class);
                            String sam = "";

                            ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData());
                            listview.setAdapter(adapter);
                           // listview.setStackFromBottom(true);
                          //  Util.showMessage(Chat.this,"Merhabalar");
                        }
                    });

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    t.start();

必要な場合は、

@Override
protected void onDestroy() {
    super.onDestroy();
    Thread.interrupted();
    //t.interrupted();
}
于 2018-01-16T17:25:27.847 に答える
0

私はこのようにそれを行い、それはうまく機能します(コードはKotlinで書かれています):

private lateinit var runnable: Runnable

private var handler = Handler(Looper.getMainLooper())

private val repeatPeriod: Long = 10000

次に、関数内からランナブルを再初期化します

runnable = Runnable {

        // Your code goes here

        handler.postDelayed(runnable, repeatPeriod)

    }

    handler.postDelayed(runnable, repeatPeriod)

}

ハンドラーを2回postDelayしないと、ループは完全ではなくなることに注意してください。

于 2021-05-04T19:16:53.077 に答える