jason adams jason adams - 6 months ago 53
Android Question

Skipped 130+ frames, too much work on the main thread

I understand that network calls and sqlite accesses are best done through worker threads. In my case, my network calls are done thru Okhttp and the sqlite are done thru one single worker thread.

So here's my problem. I have a main activity that holds all the stocks that the user has bought in a listview. Every time this new activity is created, the

onCreate
method will go through the stocks in the database and update them one by one and then update the listview.

This of course puts too much strain on the main thread. But my problem is how can I design this better? Right now I have something like this within the
onCreate
:

Thread t1 = new Thread(new Runnable{
@Override
public void run(){
// access sqlite
positionsArray = retrieveStocks();
}
});
t1.start();
t1.join(); //try catch omitted

Thread t2 = new Thread(new Runnable{
@Override
public void run(){
// use Okhttp to get data
positionsArray = refreshStocks();
}
});
t1.start();
t2.join(); //try catch omitted

adapter = new PositionsAdapter(this, positionsArray);
listview.setAdapter(adapter);


This does not make the problem go away because the main thread still has to wait for
t1
and
t2
. Any design suggestions as to how I can fix this problem?

Answer

You should never call thread.join() on the ui thread as it will pause the app. You could use an async task to do this AsyncTask Android example

ProgressDialog progress;
private class DoNetworking extends AsyncTask<Void, Void, PosArray> {

    @Override
    protected PosArray doInBackground() {
        positionsArray = retrieveStocks();
        positionsArray = refreshStocks();
        PosArray positionsArray;
    }

    @Override
    protected void onPostExecute(PosArray positionsArray) {
        adapter = new PositionsAdapter(this, positionsArray);
        listview.setAdapter(adapter); 
        progress.dismiss();
    }
}
progress = ProgressDialog.show(this, "dialog title","dialog message", true);
new DoNetworking().execute()