Android Progress bar code and Progress bar refreshing
Today I saw a discussion about the slow progress bar. The actual problem is that the program execution speed in the background is very fast, but the progress bar on the interface is relatively slow. To this end, a small experiment was conducted to increase the progress bar to 100% in one second (1% increase every 10 ms and 25% increase every ms ), verify which method gives people a quick feeling, but after the demo is made, we have found a new problem and want to discuss it with you here.
Problem
According to the Code, the expected result is that the two progress bars increase at the same speed, but after my test, click the Add button at the same time, increasing the progress bar by jumping is always faster than increasing the progress bar gradually.
The interface is as follows (the source code and layout file are later ):
Analysis:
Update SS through the Handler mechanism. After clicking the "Add at the same time" button, post two Runnable objects to the Message Queue respectively, and then execute the run method in Runnable, after the progress value is increased, a message is sent to the message Queue. Then, handleMessage is sent, the progress bar is updated, and the Runnable object is post respectively... Wait until the progress bar is full.
Current conclusion
By testing the TraceView of the three execution processes "Step by Step", "skip by step", and "Add at the same time", there is no difference in the results. After reading the relevant source code, I think the time-consuming operation in the processing process is this lock. The increase of 1% every 10 ms is too frequent to send messages and frequent interface updates, which will lead to a slow increase. I don't know how you can read this question.
Before pasting the source code, I would like to say that some codes found online that use Handler to update the progress bar are problematic. Before removeCallbacks, he post runnable again, which causes the previous runnable to be removed and a new runnable to be added. In this way, the system loops infinitely and occupies resources.
Demo
MainActivity. java
package com.example.progress;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;public class MainActivity extends Activity implements OnClickListener{ private static final int PERCENT_TOTAL = 100; ProgressBar mProgressFluency, mProgressJumpy; int percentFluency = 0; int percentJumpy = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProgressFluency = (ProgressBar) findViewById(R.id.progressBar1); mProgressJumpy = (ProgressBar) findViewById(R.id.progressBar2); ((Button) findViewById(R.id.button_fluency)).setOnClickListener(this); ((Button) findViewById(R.id.button_jumpy)).setOnClickListener(this); ((Button) findViewById(R.id.button_reset)).setOnClickListener(this); ((Button) findViewById(R.id.button_syn_increase)).setOnClickListener(this); } final Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case What.FLUENCY: mProgressFluency.setProgress(msg.arg1); mHandler.post(mUpdateProgressFluency); break; case What.JUMPY: mProgressJumpy.setProgress(msg.arg1); mHandler.post(mUpdateProgressJumpy); break; default: break; } } }; static class What { final static int FLUENCY = 1; final static int JUMPY = 2; } final Runnable mUpdateProgressFluency = new Runnable() { final int everyTimeAddF = 1; final int delay = 1000 / (100 / everyTimeAddF); @Override public void run() { percentFluency += everyTimeAddF; if (percentFluency > PERCENT_TOTAL) { mHandler.removeCallbacks(mUpdateProgressFluency); } else { Message msg = mHandler.obtainMessage(); msg.arg1 = percentFluency; msg.what = What.FLUENCY; mHandler.sendMessageDelayed(msg, delay); } } }; final int everyTimeAdd = 25; final int delay = 1000 / (100 / everyTimeAdd); final Runnable mUpdateProgressJumpy = new Runnable() { @Override public void run() { percentJumpy += everyTimeAdd; if (percentJumpy > PERCENT_TOTAL) { mHandler.removeCallbacks(mUpdateProgressJumpy); } else { Message msg = mHandler.obtainMessage(); msg.arg1 = percentJumpy; msg.what = What.JUMPY; mHandler.sendMessageDelayed(msg, delay); } } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_fluency: percentFluency = 0; mProgressFluency.setVisibility(View.VISIBLE); mHandler.post(mUpdateProgressFluency); break; case R.id.button_jumpy: percentJumpy = 0; mProgressJumpy.setVisibility(View.VISIBLE); mHandler.post(mUpdateProgressJumpy); break; case R.id.button_reset: mHandler.removeCallbacks(mUpdateProgressFluency); mProgressFluency.setProgress(0); mHandler.removeCallbacks(mUpdateProgressJumpy); mProgressJumpy.setProgress(0); break; case R.id.button_syn_increase: percentFluency = 0; mProgressFluency.setVisibility(View.VISIBLE); mHandler.post(mUpdateProgressFluency); percentJumpy = 0; mProgressJumpy.setVisibility(View.VISIBLE); mHandler.postDelayed(mUpdateProgressJumpy, delay); break; default: break; } }}