Android Progress進度條程式碼,進度條重新整理問題探討
轉載註明出處,Lee http://blog.csdn.net/hnulwt/article/details/44462177
今天看到討論說關於進度條走的慢的問題。實際問題是這樣的:後臺執行的程式速度會很快,但是在介面上感覺得到進度條是走的比較慢的。為此,做了一個小實驗,程式碼上實驗在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;
}
}
}
佈局檔案
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cn.wps.progress.MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/button_fluency"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="逐步增加" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button_jumpy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="跳躍增加" />
</LinearLayout>
<Button
android:id="@+id/button_syn_increase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="同時增加" />
<Button
android:id="@+id/button_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重置" />
</LinearLayout>