在这里,我们将给大家分享关于C++BoostASIO简单的定期计时器?的知识,让您更了解c++定时器使用的本质,同时也会涉及到如何更有效地android–如何停止尚未完成的计时器然后启动一个新计时器?
在这里,我们将给大家分享关于C ++ Boost ASIO简单的定期计时器?的知识,让您更了解c++定时器使用的本质,同时也会涉及到如何更有效地android – 如何停止尚未完成的计时器然后启动一个新计时器?、android – 如何在ListView中处理多个倒计时计时器?、android-如何取消计时器并更新相同的计时器?、boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记的内容。
本文目录一览:- C ++ Boost ASIO简单的定期计时器?(c++定时器使用)
- android – 如何停止尚未完成的计时器然后启动一个新计时器?
- android – 如何在ListView中处理多个倒计时计时器?
- android-如何取消计时器并更新相同的计时器?
- boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记
C ++ Boost ASIO简单的定期计时器?(c++定时器使用)
我希望一个非常简单的定期计时器每50毫秒调用一次我的代码。我可以使一个线程一直保持50ms的睡眠时间(但这很痛苦)……我可以开始研究Linux
API来制作定时器(但它不是可移植的)……
我 想 使用boost。我只是不知道这是可能的。Boost是否提供此功能?
答案1
小编典典Boosts Asio教程中的第二个示例对此进行了解释。
你可以在这里找到它。
之后,请查看第三个示例,以了解如何以周期性的时间间隔再次调用它
android – 如何停止尚未完成的计时器然后启动一个新计时器?
我正在尝试做各种各样的猜谜游戏.问题是我的计时器在回答问题(按下按钮)并启动新计时器后流入下一个计时器.这导致两个定时器以不同的间隔改变文本视图,这不是它应该如何.我想知道如何停止我之前的倒计时并开始一个新的倒计时.谢谢!这是我的代码:
button.setonClickListener(new View.OnClickListener() {
public void onClick(View v) {
final TextView textic = (TextView) findViewById(R.id.button1);
long total = 30000;
final CountDownTimer Count = new CountDownTimer(total, 1000) {
public void onTick(long millisUntilFinished) {
textic.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
textic.setText("OUT OF TIME!");
finish();
}
};
Count.start();
解决方法:
我没有测试代码,但我会使用这样的东西:
final TextView textic = (TextView) findViewById(R.id.button1);
final android.os.CountDownTimer Count = new android.os.CountDownTimer(total, 1000) {
public void onTick(long millisUntilFinished) {
textic.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
textic.setText("OUT OF TIME!");
}
};
button.setonClickListener(new View.OnClickListener() {
public void onClick(View v) {
Count.cancel();
Count.start();
}
});
android – 如何在ListView中处理多个倒计时计时器?
例如,如果我的列表包含4个项目,我将有4行.
在这一点上,我需要处理4个不同的倒计时(每行一个),因为时间不同.
到目前为止,我使用以下方式处理它:在自定义列表适配器中,在getView()方法内部,我创建一个新的CountDownTimer,并在TextView中显示剩余时间.
但是问题是它减慢了很多活动,甚至在最坏的情况下甚至无法正确滚动(因为每次显示一行,都会创建一个新的CountDownTimer).
我搜索了很多更好的解决方案,但没有人满意.
有没有更清洁和更平滑的解决方案来处理listView中的多个倒计时计时器?
谢谢
解决方法
请按照以下示例代码,让我知道:
主要活动 :
public class MainActivity extends Activity { private ListView lvItems; private List<Product> lstProducts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvItems = (ListView) findViewById(R.id.lvItems); lstProducts = new ArrayList<>(); lstProducts.add(new Product("A",System.currentTimeMillis() + 10000)); lstProducts.add(new Product("B",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("C",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("D",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("E",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("F",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("G",System.currentTimeMillis() + 30000)); lstProducts.add(new Product("H",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("I",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("J",System.currentTimeMillis() + 40000)); lstProducts.add(new Product("K",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("L",System.currentTimeMillis() + 50000)); lstProducts.add(new Product("M",System.currentTimeMillis() + 60000)); lstProducts.add(new Product("N",System.currentTimeMillis() + 20000)); lstProducts.add(new Product("O",System.currentTimeMillis() + 10000)); lvItems.setAdapter(new CountdownAdapter(MainActivity.this,lstProducts)); } private class Product { String name; long expirationTime; public Product(String name,long expirationTime) { this.name = name; this.expirationTime = expirationTime; } } public class CountdownAdapter extends ArrayAdapter<Product> { private LayoutInflater lf; private List<ViewHolder> lstHolders; private Handler mHandler = new Handler(); private Runnable updateRemainingTimeRunnable = new Runnable() { @Override public void run() { synchronized (lstHolders) { long currentTime = System.currentTimeMillis(); for (ViewHolder holder : lstHolders) { holder.updateTimeRemaining(currentTime); } } } }; public CountdownAdapter(Context context,List<Product> objects) { super(context,objects); lf = LayoutInflater.from(context); lstHolders = new ArrayList<>(); startUpdateTimer(); } private void startUpdateTimer() { Timer tmr = new Timer(); tmr.schedule(new TimerTask() { @Override public void run() { mHandler.post(updateRemainingTimeRunnable); } },1000,1000); } @Override public View getView(int position,View convertView,ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = lf.inflate(R.layout.list_item,parent,false); holder.tvProduct = (TextView) convertView.findViewById(R.id.tvProduct); holder.tvTimeRemaining = (TextView) convertView.findViewById(R.id.tvTimeRemaining); convertView.setTag(holder); synchronized (lstHolders) { lstHolders.add(holder); } } else { holder = (ViewHolder) convertView.getTag(); } holder.setData(getItem(position)); return convertView; } } private class ViewHolder { TextView tvProduct; TextView tvTimeRemaining; Product mProduct; public void setData(Product item) { mProduct = item; tvProduct.setText(item.name); updateTimeRemaining(System.currentTimeMillis()); } public void updateTimeRemaining(long currentTime) { long timeDiff = mProduct.expirationTime - currentTime; if (timeDiff > 0) { int seconds = (int) (timeDiff / 1000) % 60; int minutes = (int) ((timeDiff / (1000 * 60)) % 60); int hours = (int) ((timeDiff / (1000 * 60 * 60)) % 24); tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec"); } else { tvTimeRemaining.setText("Expired!!"); } } } }
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lvItems" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tvProduct" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Product Name" android:textSize="16dp" android:text/> <TextView android:id="@+id/tvTimeRemaining" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Time Remaining : " /> </LinearLayout>
android-如何取消计时器并更新相同的计时器?
我正在创建一个每30秒振动和发出蜂鸣声的应用程序,当我注销振动和发出蜂鸣声时必须取消,并且在登录振动并发出蜂鸣声时应该恢复.
注意:它必须每30秒振动并发出蜂鸣声,直到我注销为止
在我的应用中,我正在使用TimerTask进行此实现
这是使用TimerTask振动和发出蜂鸣声的代码
static TimerTask Task;
final static Handler handler = new Handler();
static Timer t = new Timer();
public static void vib() {
Task = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Vibrator vibrator = (Vibrator) ApplicationUtils.getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(3000);
playSound();
Log.d("TIMER", "Timer set on");
}
});
}
};
t.schedule(Task, 0, 30000);
}
这是我在注销部分中使用的代码
public void stopvib() {
if (Task != null) {
// Log.d("TIMER", "timer canceled");
t.cancel();
Task.cancel();
}
}
注意:我也删除了Task.cancel();.但是我仍然遇到同样的错误
我的振动工作正常,然后注销并再次登录我遇到错误
java.lang.IllegalStateException: Timer was cancelled
at java.util.Timer.scheduleImpl(Timer.java:562)
at java.util.Timer.schedule(Timer.java:481)
at com.vib(AlertListActivity.java:724)
谁能帮我这个编码.我哪里做错了?
解决方法:
我最近运行了此代码,并且工作正常.这可以使用广播Receiver来实现.您必须实现单独的CustomTimer任务来扩展TimerTask:
Activity mActivity=null;
public MyCustomTimer(Activity mActivity) {
this.mActivity=mActivity;
}
@Override
public void run() {
this.mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mActivity, "Write you code here",Toast.LENGTH_LONG).show();
Log.d("MyCustomTimer","Call");
}
});
}
之后,您必须在要实现“ vib()”方法的类中实现broadCast Receive ::
可以说,就我而言(例如)是MainActivity:
public class MainActivity extends Activity {
private MyCustomTimer myCustomTimer = null;
broadcastReceiver mBr_Start = new broadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("START_VIBRATION")) {
System.out.println("onreceive :START_VIBRATION");
vib();
}
}
};
broadcastReceiver mBr_Stop = new broadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("STOP_VIBRATION")) {
stopVibration();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("START_VIBRATION");
registerReceiver(mBr_Start, mIntentFilter);
IntentFilter mIntentFilter2 = new IntentFilter();
mIntentFilter2.addAction("STOP_VIBRATION");
registerReceiver(mBr_Stop, mIntentFilter2);
Button b1 = (Button) findViewById(R.id.button1);
b1.setonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, MySecondActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private void vib() {
myCustomTimer = new MyCustomTimer(MainActivity.this);
Timer timer = new Timer();
timer.scheduleAtFixedrate(myCustomTimer, 0, 30000);
}
private void stopVibration() {
Log.d("MainActivity", "Before Cancel");
if (null != myCustomTimer)
myCustomTimer.cancel();
Log.d("MainActivity", "After Cancel");
}
}
现在,您可以通过实现以下几行来开始或停止振动:
开始振动:
Intent i=new Intent("START_VIBRATION");
mActivity.sendbroadcast(i);
停止:
Intent i=new Intent("STOP_VIBRATION");
mActivity.sendbroadcast(i);
注意:
MainActivity的onDestroy()(在您的情况下,在实现broadcast Receiver的地方,取消注册broadcastReceiver.)
boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记
asio 库基于操作系统提供的异步机制,采用前摄器设计模式 (Proactor) 实现了可移植的异步 (或者同步) IO 操作,而且并不要求多线程和锁定,有效地避免了多线程编程带来的诸多有害副作用。
目前 asio 主要关注于网络通信方面,使用大量的类和函数封装了 socket API,支持 TCP、TCMP、UDP 等网络通信协议。但 asio 的异步操作并不局限于网络编程,它还支持串口读写、定时器、SSL 等功能,而且 asio 是一个很好的富有弹性的框架,可以扩展到其他有异步操作需要的领域
概述
asio 库基于前摄器模式封装了操作系统的 select、poll/epoll、kqueue、overlapped I/O 等机制,实现了异步 IO 模型。它的核心类 io_service,相当于前摄器模式中的 Proactor 角色,asio 的任何操作都需要有 io_service 的参与。
在同步模式下,程序发起一个 IO 操作,向 io_service 提交请求,io_service 把操作转交给操作系统,同步地等待。当 IO 操作完成时,操作系统通知 io_service,然后 io_service 再把结果发回给程序,完成整个同步流程。这个处理流程与多线程的 join () 等待方式很相似。
在异步模式下,程序除了要发起的 IO 操作,还要定义一个用于回调的完成处理函数。io_service 同样把 IO 操作转交给操作系统执行,但它不同步等待,而是立即返回。调用 io_service 的 run () 成员函数可以等待异步操作完成,当异步操作完成时 io_service 从操作系统获取执行结果,调用完成处理函数。
asio 不直接使用操作系统提供的线程,而是定义了一个自己的线程概念:strand,它保证在多线程的环境中代码可以正确地执行,而无需使用互斥量。io_service::strand::wrap () 函数可以包装一个函数在 strand 中执行。
asio 库使用 system 库的 error_code 和 system_error 来表示程序运行的错误。
定时器
定时器是 asio 库里最简单的一个 IO 模型示范,提供等待时间终止的功能,通过它我们可以快速熟悉 asio 的基本使用方法:
同步定时器
[cpp] view plain copy
print?
- #include "stdafx.h"
- #include "boost/asio.hpp"
- #include "boost/date_time/posix_time/posix_time.hpp"
- #include "iostream"
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- boost::asio::io_service ios; // 所以的 asio 程序必须要有一个 io_service 对象
- // 定时器 io_service 作为构造函数参数,两秒钟之后定时器终止
- boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2));
- cout << t.expires_at() << endl; // 查看终止的绝对事件
- t.wait(); // 调用 wait 同步等待
- cout << "hello asio" << endl;
- return 0;
- }
可以把它与 thread 库的 sleep () 函数对比研究一下,两者都是等待,但内部机制完成不同:thread 库的 sleep () 使用了互斥量和条件变量,在线程中等待,而 asio 则是调用了操作系统的异步机制,如 select、epoll 等完成的。
异步定时器
下面的是异步定时器,代码大致与同步定时器相等,增加了回调函数,并使用 io_service.run () 和定时器的 async_wait () 方法
[cpp] view plain copy
print?
- #include "stdafx.h"
- #include "boost/asio.hpp"
- #include "boost/date_time/posix_time/posix_time.hpp"
- #include "iostream"
- using namespace std;
- void Print(const boost::system::error_code& error)
- {
- cout << "hello asio" << endl;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- boost::asio::io_service ios; // 所以的 asio 程序必须要有一个 io_service 对象
- // 定时器 io_service 作为构造函数参数,两秒钟之后定时器终止
- boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2));
- t.async_wait(Print); // 调用 wait 异步等待
- cout << "it show before t expired." << endl;
- ios.run();
- return 0;
- }
代码的前两行与同步定时器相同,这是所有 asio 程序基本的部分。重要的是异步等待 async_wait (),它通知 io_service 异步地执行 io 操作,并且注册了回调函数,用于在 io 操作完成时由事件多路分离器分派返回值 (error_code) 调用
最后必须调用 io_service 的 run () 成员函数,它启动前摄器的事件处理循环,阻塞等待所有的操作完成并分派事件。如果不调用 run () 那么虽然操作被异步执行了,但没有一个等待它完成的机制,回调函数将得不到执行机会。
异步定时器使用 bind
异步定时器中由于引入了回调函数,因此产生了很多的变化,可以增加回调函数的参数,使它能够做更多的事情。但 async_wait () 接受的回调函数类型是固定的,必须使用 bind 库来绑定参数以适配它的接口
下面实现一个可以定时执行任意函数的定时器 AsynTimer (asyctimer),它持有一个 asio 定时器对象和一个计数器,还有一个 function 对象来保存回调函数
[cpp] view plain copy
print?
- #include "stdafx.h"
- #include "boost/asio.hpp"
- #include "boost/date_time/posix_time/posix_time.hpp"
- #include "boost/bind.hpp"
- #include "boost/function.hpp"
- #include "iostream"
- using namespace std;
- class AsynTimer
- {
- public:
- template<typename F> // 模板类型,可以接受任意可调用物
- AsynTimer(boost::asio::io_service& ios, int x, F func)
- :f(func), count_max(x), count(0), // 初始化回调函数和计数器
- t(ios, boost::posix_time::millisec(500)) // 启动计时器
- {
- t.async_wait(boost::bind(&AsynTimer::CallBack, // 异步等待计时器
- this, boost::asio::placeholders::error)); // 注册回调函数
- }
- void CallBack(const boost::system::error_code& error)
- {
- if (count >= count_max) // 如果计数器达到上限则返回
- {
- return;
- }
- ++count;
- f(); // 调用 function 对象
- // 设置定时器的终止时间为 0.5 秒之后
- t.expires_at(t.expires_at() + boost::posix_time::microsec(500));
- // 再次启动定时器,异步等待
- t.async_wait(boost::bind(&AsynTimer::CallBack, this, boost::asio::placeholders::error));
- }
- private:
- int count;
- int count_max;
- boost::function<void()> f; // function 对象,持有无参无返回值的可调用物
- boost::asio::deadline_timer t; // asio 定时器对象
- };
- // 第一个回调函数
- void print1()
- {
- cout << "hello asio" << endl;
- }
- // 第二个回调函数
- void print2()
- {
- cout << "hello boost" << endl;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- boost::asio::io_service ios;
- AsynTimer t1(ios, 10, print1); // 启动第一个定时器
- AsynTimer t2(ios, 10, print2); // 启动第二个定时器
- ios.run(); // io_service 等待异步调用结束
- return 0;
- }
注意在 async_wait () 中 bind 的用法,CallBack 是 AsynTimer 的一个成员函数,因此需要绑定 this 指针,同时还使用了 asio 下子名字空间 placeholders 下的一个占位符 error,他的作业类似于 bind 库的占位符_1、_2,用于传递 error_code 值。
接下来是 AsynTimer 的主要功能函数 CallBack,它符合 async_wait () 对回调函数的要求,有一个 error_code 参数,当定时器终止时它将被调用执行
CallBack 函数内部累加器,如果计数器未达到上限则调用 function 对象 f,然后重新设置定时器的终止时间,再次异步等待被调用,从而达到反复执行的目的
今天关于C ++ Boost ASIO简单的定期计时器?和c++定时器使用的介绍到此结束,谢谢您的阅读,有关android – 如何停止尚未完成的计时器然后启动一个新计时器?、android – 如何在ListView中处理多个倒计时计时器?、android-如何取消计时器并更新相同的计时器?、boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记等更多相关知识的信息可以在本站进行查询。
本文标签: