Note that there are some explanatory texts on larger screens.

plurals
  1. POIndeterminate ProgressBar is making my background thread really slow
    text
    copied!<p>I have an app with heavy background work. To keep my UI alive (and avoid ANR) I have an indeterminate ProgressBar that I display before the background work and hide when I finish it.</p> <p>This is how my progress bar is declared in my activity's xml:</p> <pre><code>&lt;ProgressBar style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:indeterminate="true" android:visibility="gone" /&gt; </code></pre> <p>I toggle the visibility before and after my background operations:</p> <pre><code>this.runOnUiThread(new Runnable() { @Override public void run() { Activity.this.progress.setVisibility(View.VISIBLE); } }); this.runOnUiThread(new Runnable() { @Override public void run() { Activity.this.progress.setVisibility(View.GONE); } }); </code></pre> <p>On my Activity's constructor:</p> <pre><code>this.progress = (ProgressBar) findViewById(R.my_activity.progress_id); </code></pre> <p>My background work is really heavy (include native calls), but I create a new Runnable to do the job.</p> <p>The problem is: With the progressBar, the time to background thread finish the work grows about 300ms per second. When I run the traceview, I can see that every time my ProgressBar refresh, it stops the background thread to update the view.</p> <p>I tried two approaches:</p> <ol> <li>Setting the background thread's priority to MAX_PRIORITY.</li> <li>Creating a custom animation with refresh rate of 300ms (The default is 50ms).</li> </ol> <p>With these two combined, the time of one of my operations come from 5900ms to 4700ms but, with lower refresh rate, the progress bar isn't smooth and I'm afraid that setting the background thread priority to MAX isn't safe.</p> <p>Is there anything more that I can do?</p> <hr> <p>Edit:</p> <p>AsyncTask is really impossible to refactor now.</p> <p>My updated code with the Chuck Norris's solution:</p> <pre><code>Activity.this.getHandler().sendEmptyMessage( MyMessages.SHOW_PROGRESS_BAR); Activity.this.getHandler().sendEmptyMessage( MyMessages.HIDE_PROGRESS_BAR); </code></pre> <p>and</p> <pre><code>private Handler handler = new Handler() { @Override public void handleMessage(android.os.Message msg) { switch (msg.what) { case MyMessages.SHOW_PROGRESS_BAR: Activity.this.progress.setVisibility(View.VISIBLE); break; case MyMessages.HIDE_PROGRESS_BAR: Activity.this.progress.setVisibility(View.GONE); break; default: break; } }; }; </code></pre> <p>This really improved my application and I don't need to set Thread Priority to Max anymore, and that was one of my goals.</p> <p>But I still want to put my animation back to Android's default (with refresh of ProgressBar every 50ms). When I do that, I lose 1s in my benchmark operation.</p> <p>My benchmark:</p> <p>Average time of the same operation:</p> <ol> <li>Without handler and android's default progress bar: 5.1s</li> <li>With handler and android's default progress bar: 4.6s (same result of Thread priority to MAX)</li> <li>With handler and custom animation refreshing every 300ms: 3.5s</li> <li>With handler and custom animation refreshing every 150ms: 3.8s</li> </ol> <p>Any idea?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload