Android Progress進度條代碼,進度條重新整理問題探討
今天看到討論說關於進度條走的慢的問題。實際問題是這樣的:後台執行的程式速度會很快,但是在介面上感覺得到進度條是走的比較慢的。為此,做了一個小實驗,代碼上實驗在1秒的時間 通過倆種方式增加進度條至100%(每隔10ms增加1%和 每隔250ms增加25%),驗證哪種方式給人的感覺快,但是在demo做出來之後,確發現了新的問題,想在此與大家共同討論。
問題
根據代碼,我預想的結果應該是倆個進度條增加的速度相同,但是經過我的測試,點擊 同時增加 按鈕,跳躍增加那個進度條總是會比逐步增加的進度條要快。
介面如下(源碼及布局檔案在後面):
分析:
通過Handler機制更新Progress,在點擊“同時增加”按鈕後,分別post兩個Runnable對象到訊息佇列,然後執行Runnable裡面的run方法,在進度數值增加後 發送message到訊息佇列,最後handleMessage,更新進度條,然後再分別post Runnable對象。。。如此迴圈直到進度條滿。
目前的結論
通過測試 “逐步增加”“跳躍增加”“同時增加”三個執行過程的TraceView,結果看不出有什麼差別。看了相關的源碼,覺得在處理過程中耗時操作就是this鎖了吧。由於每隔10ms增加1%發送訊息太頻繁、介面更新也頻繁,會導致逐步增加的速度偏慢。不知各位大神如何看這個問題,希望大家不吝賜教。
在貼源碼之前先說一句,網上查到的一些利用Handler更新進度條的代碼是有問題的。他在removeCallbacks之前又post了runnable,導致remove掉上一個runnable後又加入一個新的runnable,這樣無限迴圈下去,佔用資源。
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; } }}