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()
呼び出しが必要です。
サービスを作成し、onCreate()
にロジックを入れてみませんか。この場合、戻るボタンを押してもサービスは実行を続けます。そして、アプリケーションに入ると、onCreate()
を再度呼び出しません。むしろ、onStart()
を呼び出します
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);
おそらく、これを達成するためにアクティビティのライフサイクルメソッドが含まれます。
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の呼び出しも停止します。
このようにコードを簡素化できます。
Javaの場合:
new Handler().postDelayed (() -> {
//your code here
}, 1000);
コトリンで:
Handler().postDelayed({
//your code here
}, 1000)
あなたが同じアクティビティをしているときに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);
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);
複数のインスタンスのように聞こえるので、さまざまなアクティビティフラグを試すことができると思います。
「singleTop」「singleTask」「singleInstance」
私が試すものは、マニフェスト内で定義できます。
http://developer.Android.com/guide/topics/manifest/activity-element.html
Manifest.xmlでアクティビティを起動するにはandrid:allowRetainTaskState = "true"を設定する必要があります。このアクティビティが起動アクティビティでない場合。このアクティビティでAndroid:launchMode = "singleTask"を設定する必要があります