배경 작업이 많은 앱이 있습니다. 내 UI를 유지하려면 (그리고 ANR을 피하기 위해) 배경 작업 전에 표시하고 완료 할 때 숨기는 불확실한 ProgressBar가 있습니다. 내가 전에 내 배경 작업 후 가시성을 전환Indeterminate ProgressBar로 인해 백그라운드 스레드가 실제로 느려짐
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:indeterminate="true"
android:visibility="gone" />
:
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);
}
});
을 내 작업의 생성자에 :
이 내 진행률 표시 줄이 내 활동의 XML로 선언하는 방법입니다
this.progress = (ProgressBar) findViewById(R.my_activity.progress_id);
내 배경 작업이 너무 무거워 (기본 전화 포함), 새로운 작업을 수행 할 수있는 Runnable.
문제는 progressBar를 사용하면 백그라운드 스레드 마무리 시간이 초당 약 300ms 가량 늘어납니다. 트레이스 뷰를 실행하면 ProgressBar가 새로 고침 될 때마다 뷰를 업데이트하기 위해 백그라운드 스레드가 중지된다는 것을 알 수 있습니다. MAX_PRIORITY에 백그라운드 스레드의 우선 순위를 설정
- : 나는 두 가지 방법을 시도했다.
- 새로 고침 빈도가 300ms 인 사용자 지정 애니메이션 만들기 (기본값은 50ms 임).
이 둘을 결합하면 내 작업 시간이 5900ms에서 4700ms로 증가하지만 재생 빈도가 낮을수록 진행률 막대가 부드럽지 않고 백그라운드 스레드 우선 순위를 MAX로 설정하는 것이 두려워요. 안전하지 않습니다.
내가 할 수있는 것 이상의 것이 있습니까?
편집 :
AsyncTask를 이제 리팩토링 정말 불가능하다. 척 노리스의 솔루션
내 업데이트 된 코드는 :
Activity.this.getHandler().sendEmptyMessage(
MyMessages.SHOW_PROGRESS_BAR);
Activity.this.getHandler().sendEmptyMessage(
MyMessages.HIDE_PROGRESS_BAR);
및
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;
}
};
};
이 정말 내 응용 프로그램을 개선하고 더 이상 최대로 스레드 우선 순위를 설정할 필요가 없습니다, 그리고이었다 내 목표 중 하나.
하지만 여전히 애니메이션을 Android의 기본값 (ProgressBar를 50ms마다 새로 고침 함)으로 되돌리고 싶습니다. 그렇게하면 벤치 마크 작업에서 1 초를 잃습니다.
내 벤치 마크 : 동일한 작업의
평균 시간 : 핸들러와 안드로이드의 기본 진행 표시 줄과 함께 5.1s
- 4.기가 (MAX에 스레드 우선 순위 같은 결과) 핸들러 모든 300ms를 새로 고침 사용자 지정 애니메이션
- : 3.8s
어떤 생각 : 모든 150ms의 상쾌한 핸들러와 3.5 초
설명은 전체를 제어 할 수 AsyncTask를 사용하지 않을 이유가 있나요입니까? –
리펙터를 수행하는 앱의 크기와 작업량이 크기 때문입니다. 벌써 예정되어 있지만, 지금 당장 할 시간이 없습니다. 그러나이 문제를 해결하기 위해 AsyncTasks를 만드는 것은 해결 될 것입니까? 나는 오늘 POC를 만들려고 노력할 것이다 –
그래, 나는 onPreExecute에서 진행 막대를 시작하고 onPostExecute를 멈추면 당신이 묘사하는 행동을 표시하지 않을 것이라고 기대할 것이다 ... 확실히 가치있는 테스트 –