在我的项目中,我想在另一个线程中实现一个计时器,该计时器会减少在我的应用程序中执行某个方法所花费的时间,如果花费太多时间就会做一些事情。当执行MyManager.startCommand()方法时,应用程序冻结,我不知道为什么,因为我认为我没有在UI线程上做任何事情。我的代码有什么问题吗?
我最初问过这个问题并没有遇到应用程序冻结,所以我不认为这是因为我正在睡觉:Runnable posted in another runnable not executed。
public class MyManager{
private MyManager sInstance;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Runnable mTimeoutTimer;
public static MyManager getInstance(){
if(sInstance == null){
sInstance = new MyManager();
}
return sInstance;
}
private MyManager(){
mHandlerThread = new HandlerThread("mHandlerThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mTimeoutTimer = new Runnable() {
@Override
public void run() {
Log.e(“RUNNABLE RUNNING!”);
}
};
public class MyCommand {
private Runnable myRun;
public MyCommand(){
myRun = new Runnable() {
@Override
public void run() {
MyManager.getInstance().startTimeoutTimer();
MyCommand.this.run();
}
};
}
public void execute() {
myRun.run();
}
abstract public void run();
}
private void startTimeoutTimer(){
mHandler.post();
}
public void startCommand(){
new MyCommand().execute();
}
}
我是如何使用MyCommand对象的:
MyCommand command =
new MyCommand() {
@Override
public void run() {
//make api call that happens in another thread
}
};
所以我基本上是在尝试为该API调用创建超时计时器。
答案 0 :(得分:1)
试试这个:
将第一个runnable包装在一个Thread中。
public class MyManager{
private MyManager sInstance;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Runnable mTimeoutTimer;
public static MyManager getInstance(){
if(sInstance == null){
sInstance = new MyManager();
}
return sInstance;
}
private MyManager(){
mHandlerThread = new HandlerThread();
mHandler = new Handler(mHandlerThread.getLooper());
mTimeoutTimer = new Runnable() {
@Override
public void run() {
Log.e(“RUNNABLE RUNNING!”);
}
};
public class MyCommand {
private Thread th;
private Runnable myRun;
public MyCommand(){
myRun = new Runnable() {
@Override
public void run() {
MyManager.getInstance().startTimeoutTimer();
try {
Thread.sleep(COMMAND_TIMEOUT_MILLIS * 3);
} catch (InterruptedException e) {}
MyCommand.this.execute();
}
};
th = new Thread(myRun);
}
public void execute() {
th.start();
mHandler.postDelayed(mTimeoutTimer);
}
}
private void startTimeoutTimer(){
mHandlerThread.start();
mHandler.postDelayed(mTimeoutTimer);
}
public void startCommand(){
new MyCommand().execute();
}
}
你也忘了开始mHandlerThread
private void startTimeoutTimer(){
mHandlerThread.start();
mHandler.postDelayed(mTimeoutTimer);
}