1

Currently I have a button that loads an activity.

That activity has a ListView in it that for whatever reason takes a fairly long time to load(not waiting for data, the data is already in memory). The problem is that while it's rendering the list, the UI is waiting where the button was clicked, and doesn't change screen until the list has fully loaded.

What I'd like, is to only display the list once the activity is loaded, so at least something happens as soon as they press the button(responsive UI is important).

Currently, my hack around solution to this, is to spawn a thread, wait for 50 milliseconds, and then set the adapter for my list(using runOnUiThread). Of course, if the activity takes longer than 50ms to load on some phones, then it'll have to load the entire list to load the activity again.

Current relevant code:

@Override
public void onPostResume() {
    super.onPostResume();
    new Thread(new Runnable() {
        @Override
        public void run() {
            final AdapterData data = getData();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    myAdapter = new MyAdapter(MyActivity.this, data);
                    lvMyList.setAdapter(myAdapter);
                }
            });
        }
    }).start();
}

I just changed variable names in the code, but that's not relevant. This is just so you can see my general solution.

I feel like there should be some kind of callback that's called when the activity finishes creating. I thought that onPostResume waited for the activity to finish loading, but that did not work. It still hung.

Cruncher
  • 7,641
  • 1
  • 31
  • 65
  • As a first solution, I would suggest to create a static public Runnable variable inside the launched activity, that you can execute when the loading has finished. Is it enough? – Beppi's Dec 21 '16 at 17:28
  • I don't understand what you're asking me to do. "that you can execute when the loading has finished". My issue is that I don't know when the loading has finished. I know how to launch a runnable, as you can see in my posted solution. My issue is knowing when to execute it, as waiting 50ms feels like a VERY poor solution – Cruncher Dec 21 '16 at 17:30
  • Sorry maybe I'm not understanding when exactly in the code the lag is. Do you have to wait for getData() to end? Or does it take too long to display after loading? I'm actually missing the point, probably... :/ – Beppi's Dec 21 '16 at 17:40
  • @Beppi's The current code *works*. It's just a bad solution. getData does not wait. The waiting time is for the listview to render when I've set the adapter. – Cruncher Dec 21 '16 at 18:56

1 Answers1

6

you can use IdleHandler

protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.xxx);  
    final AdapterData data = getData();
    IdleHandler handler = new IdleHandler() {  

        @Override  
        public boolean queueIdle() {  
            myAdapter = new MyAdapter(MyActivity.this, data);
            lvMyList.setAdapter(myAdapter);
            return false;  
        }   
    };  
    Looper.myQueue().addIdleHandler(handler);  

}  
peter zhang
  • 156
  • 4
  • going to give this a shot today and let you know how it works out. Thanks for the answer – Cruncher Dec 22 '16 at 14:40
  • Hi peter, this appears to handle what I need exactly. Thank you very much for your answer. I'm surprised I couldn't find this googling anywhere! Quick question: What does the return value signify? In what case would you return true? – Cruncher Dec 22 '16 at 14:56
  • 1
    Last question: is this a good practice in general? Are idle handlers used frequently? – Cruncher Dec 22 '16 at 15:17
  • 1
    Return true to keep your idle handler active, false to have it removed.when ui thread is going to block waiting for more messages queueIdle() will be trigger。 – peter zhang Dec 23 '16 at 02:31
  • fyi. https://developer.android.com/reference/android/os/MessageQueue.html – peter zhang Dec 23 '16 at 02:33
  • how safe is to use this? can we be 100% sure this will be called no matter the android version? this seems like a great solution :) thanks. – einschneidend Apr 04 '20 at 19:24