0

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?

jason adams
  • 545
  • 2
  • 15
  • 30
  • Your on create method should a "loading" text while you wait for the Threads to complete – RMalke May 19 '16 at 17:51
  • How about using Loader?( https://developer.android.com/reference/android/app/LoaderManager.html ) You can show the loading text (or cached data) first then refresh the data after loading completed. – chartsai May 19 '16 at 17:56
  • yes, but I'm still skipping 130+ frames, I'm still getting that warning that there's too much work done on the main thread. – jason adams May 19 '16 at 17:57
  • @Chatea that sounds like a good idea, also, not sure but would adding services be of any help here? – jason adams May 19 '16 at 17:59
  • 1
    Service is used to do something when your app is not in foreground. If you only need to do something in non-UI thread, try AsyncTask, AsyncLoader, or IntentService. I think you should determine "when to load the network data" first. – chartsai May 19 '16 at 18:03
  • 1
    Why are you calling `join()` from the UI thread? Calling `join()` pauses the current thread until the other thread has finished. That means your Threads have no benefit. – adelphus May 19 '16 at 18:05

1 Answers1

1

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()
Community
  • 1
  • 1
Tomer Shemesh
  • 10,278
  • 4
  • 21
  • 44
  • so if I use async task to set the adapter, wouldn't the main thread still have to wait for the results to get back? Wouldn't the main thread still wait for the listview to be set before it can draw it on the screen? – jason adams May 19 '16 at 23:54
  • yea the main screen wont update until the data comes back but the screen wont be frozen like th way you had it. Its your job to load up a progress bar or progress dialog while the user waits. Iv added an example for you – Tomer Shemesh May 19 '16 at 23:57
  • Ah, ok I see, so let me get this straight, using AsyncTask would allow the activity to draw things without it getting blocked, and it can wait on AsyncTask for as long as it takes? Also would calling Okhttp, in order to make network calls, within AsyncTask reasonable? – jason adams May 20 '16 at 00:03
  • 1
    Yes, Actually thats the whole point async task was made. for making networking calls and doing things without blocking threads – Tomer Shemesh May 20 '16 at 15:57