본문
[2017.11.16] 73. Android 음악 플레이어 프로젝트 [최적화 3 - Thread 병렬처리]
도입
이번 포스팅에서는 Next, Prev 버튼으로 음악을 넘길 때 Viewpager가 버벅거렸던 것을 해결할 예정이다!
문제점 1
Next, Prev 음악을 선택하면 Viewpager가 조금 느려지는 현상이 발생했지만 음악이 변경되는데 이정도면 괜찮지 않나... 라는 안일한 생각을 했고 넘겼다. 그러나 다른 음악 플레이어와 비교했을 때 확실히 버벅거린다고 느껴 원인 파악을 시작했다.
Viewpager가 버벅거렸던 것의 원인이
1) 이미지 로딩
2) 잘못된 설계
라고 생각했다...
하지만 근본적인 문제는 역시 코드였다. 역시 내 잘못..
Viewpager가 버벅거리는 원인을 파악하기 위해 Viewpager가 넘어갈 때 실행되는 코드들을 이진탐색하듯 코드를 주석 처리하며 원인을 찾았다.
그 결과!
1
2
3
4
5
6
7
8
9
|
public class PlayerController {
// ...
public void setMusic(final Uri musicUri) {
// ...
player = MediaPlayer.create(context, musicUri);
// ...
}
// ...
}
|
cs |
음악이 설정될 때마다 MediaPlayer.create로 음악이 만들어졌고 여기서 Main Thread의 리소스를 많이 사용해 버벅거리는 현상이 발생했던 것이다.
해결책 1
그래서 해당 코드를 Thread로 처리해 버벅거림 현상을 해결했다.
코드를 보면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class PlayerController {
// ...
public void setMusic(final Uri musicUri) {
// ...
new Thread() {
public void run() {
try {
player.release();
} catch (Exception e) {
} finally {
player = null;
}
player = MediaPlayer.create(context, musicUri);
player.setLooping(isLoop);
player.setOnCompletionListener((mp) -> {
currentStatus = Const.ACTION_MUSIC_NEXT;
Log.e("heepie", "finished Music");
});
play();
}
}.start();
// ...
}
// ...
}
|
cs |
문제점 2
이렇게 코드를 변경하니 버벅거리는 현상은 해결했다. 그러나 더 큰 문제가 발생했다.
빠른 속도로 음악을 변경하게 될 경우, 음악이 2개가 동시에 실행되는 문제가 발생했다.
원인 MusicPlayer를 Release하는 부분이 있지만, Thread로 병렬로 처리되기 때문에 1개의 Thread가 완료되기 전 다음 Thread가 시작되면 이전 음악은 Release되지 않는다.
해결책 2
그래서 처리방법을 고민하면서 책과 인터넷을 찾아봤다.
그 결과, MusicPlayer를 1개의 Thread만 접근 가능한 Thread-safe한 List에 담아두고 가장 마지막에 선택된 음악을 제외하고 나머지를 Release하는 방법을 선택했다. 그림으로 확인하면
Thread-safe List의 대한 실험(?)
(Thread-safe List 실습1 - http://heepie.tistory.com/201,
Thread-safe List 실습2 - http://heepie.tistory.com/202)
코드로 표현하면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class PlayerController {
// ...
public void setMusic(final Uri musicUri) {
// ...
new Thread(() -> {
// 음악 등록
player = MediaPlayer.create(context, musicUri);
player.setLooping(isLoop);
player.setOnCompletionListener((mp) -> {
currentStatus = Const.ACTION_MUSIC_NEXT;
Log.e("heepie", "finished Music");
});
play();
// 음악 추가
playerList.add(player);
// 마지막에 추가된 음악을 제외한 나머지는 모두 제거
for (int i=0; i<players.size()-1; i=i+1) {
try {
playerList.get(i).release();
} catch (Exception e) {
}
}
}).start();
// ...
}
// ...
}
|
cs |
스크린 샷
변경 후에도 음악은 1개만 실행된다.
반영 전 |
반영 후 |
|
#안드로이드 음악 플레이어 #안드로이드 mp3 #안드로이드 프로젝트 #앱개발 #모바일앱개발 #어플개발
'오렌지 플레이어 > 개발' 카테고리의 다른 글
[2017.11.29] 79. Android 음악 플레이어 프로젝트 [데이터정렬] (0) | 2017.11.29 |
---|---|
[2017.11.16] 74. Android 음악 플레이어 프로젝트 [최종 설계 및 해야 할 것] (0) | 2017.11.16 |
[2017.11.13] 72. Android 음악 플레이어 프로젝트 [최적화 2 - 설계 변경] (0) | 2017.11.15 |
[2017.11.04] 69. Android 음악 플레이어 프로젝트 [최적화 1 - 라이브러리 사용] (0) | 2017.11.04 |
[2017.11.02] 67. Android 음악 플레이어 프로젝트 [Seekbar Thread 추가] (0) | 2017.11.02 |
댓글