Using HandlerThread and Handler on a separate thread freezes UI thread

旧街凉风 提交于 2019-12-08 05:59:47

问题


In my project, I want to implement a timer in another thread that counts down the time spent executing a certain method in my application, and do something if it is taking too much time. When executing the MyManager.startCommand() method, the application is freezing and I don't know why since I think I am not doing anything on the UI thread. Is there anything wrong with my code?

I had originally asked this question and was not experiencing an app freeze, so I don't think it's because I'm sleeping the thread: 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();
    }
}

And how I'm using a MyCommand object:

MyCommand command =
new MyCommand() {
    @Override
    public void run() {
        //make api call that happens in another thread
    }
};

So I am basically trying to create the timeout timer for that API call.


回答1:


Try this:

Just wrap your first runnable in a 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();
}

}

Also you forgot to start the mHandlerThread

    private void startTimeoutTimer(){
    mHandlerThread.start();
    mHandler.postDelayed(mTimeoutTimer);

}


来源:https://stackoverflow.com/questions/24173049/using-handlerthread-and-handler-on-a-separate-thread-freezes-ui-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!