在做monkey test时出现比较高概率的死机现象,分析认为是音乐播放器出现死循环,查看代码后发现为原生设计。
代码路径:src/com/android/music/MediaPlaybackService.java
死循环发生位置为1634行,诱因为mPlayList[i] == id,mPlayerList[i]没有发生变化。根本原因在于方法removeTracksInternal(int first, int last)
场景模拟,假设first=7,last = 7,mPlayListen = 8, mPlayPos = 4,那么当代码走到1596行时,gotonext = false, num = 0,导致1595行循环不会执行,即mPlayList不会发生变化
解决方案在1594行与1595行之间添加代码
if(num == 0){
mPlayList[last] = 0;
}
1631 public int removeTrack(long id) {
1632 int numremoved = 0;
1633 synchronized (this) {
1634 for (int i = 0; i < mPlayListLen; i++) {
1635 if (mPlayList[i] == id) {
1636 numremoved += removeTracksInternal(i, i);
1637 i--;
1638 }
1639 }
1640 }
1641 if (numremoved > 0) {
1642 notifyChange(QUEUE_CHANGED);
1643 }
1644 return numremoved;
1645 }
1581 private int removeTracksInternal(int first, int last) {
1582 synchronized (this) {
1583 if (last < first) return 0;
1584 if (first < 0) first = 0;
1585 if (last >= mPlayListLen) last = mPlayListLen - 1;
1586
1587 boolean gotonext = false;
1588 if (first <= mPlayPos && mPlayPos <= last) {
1589 mPlayPos = first;
1590 gotonext = true;
1591 } else if (mPlayPos > last) {
1592 mPlayPos -= (last - first + 1);
1593 }
1594 int num = mPlayListLen - last - 1;
1595 for (int i = 0; i < num; i++) {
1596 mPlayList[first + i] = mPlayList[last + 1 + i];
1597 }
1598 mPlayListLen -= last - first + 1;
1599
1600 if (gotonext) {
1601 if (mPlayListLen == 0) {
1602 stop(true);
1603 mPlayPos = -1;
1604 if (mCursor != null) {
1605 mCursor.close();
1606 mCursor = null;
1607 }
1608 } else {
1609 if (mPlayPos >= mPlayListLen) {
1610 mPlayPos = 0;
1611 }
1612 boolean wasPlaying = isPlaying();
1613 stop(false);
1614 openCurrentAndNext();
1615 if (wasPlaying) {
1616 play();
1617 }
1618 }
1619 notifyChange(META_CHANGED);
1620 }
1621 return last - first + 1;
1622 }
1623 }
代码路径:src/com/android/music/MediaPlaybackService.java
死循环发生位置为1634行,诱因为mPlayList[i] == id,mPlayerList[i]没有发生变化。根本原因在于方法removeTracksInternal(int first, int last)
场景模拟,假设first=7,last = 7,mPlayListen = 8, mPlayPos = 4,那么当代码走到1596行时,gotonext = false, num = 0,导致1595行循环不会执行,即mPlayList不会发生变化
解决方案在1594行与1595行之间添加代码
if(num == 0){
mPlayList[last] = 0;
}
1631 public int removeTrack(long id) {
1632 int numremoved = 0;
1633 synchronized (this) {
1634 for (int i = 0; i < mPlayListLen; i++) {
1635 if (mPlayList[i] == id) {
1636 numremoved += removeTracksInternal(i, i);
1637 i--;
1638 }
1639 }
1640 }
1641 if (numremoved > 0) {
1642 notifyChange(QUEUE_CHANGED);
1643 }
1644 return numremoved;
1645 }
1581 private int removeTracksInternal(int first, int last) {
1582 synchronized (this) {
1583 if (last < first) return 0;
1584 if (first < 0) first = 0;
1585 if (last >= mPlayListLen) last = mPlayListLen - 1;
1586
1587 boolean gotonext = false;
1588 if (first <= mPlayPos && mPlayPos <= last) {
1589 mPlayPos = first;
1590 gotonext = true;
1591 } else if (mPlayPos > last) {
1592 mPlayPos -= (last - first + 1);
1593 }
1594 int num = mPlayListLen - last - 1;
1595 for (int i = 0; i < num; i++) {
1596 mPlayList[first + i] = mPlayList[last + 1 + i];
1597 }
1598 mPlayListLen -= last - first + 1;
1599
1600 if (gotonext) {
1601 if (mPlayListLen == 0) {
1602 stop(true);
1603 mPlayPos = -1;
1604 if (mCursor != null) {
1605 mCursor.close();
1606 mCursor = null;
1607 }
1608 } else {
1609 if (mPlayPos >= mPlayListLen) {
1610 mPlayPos = 0;
1611 }
1612 boolean wasPlaying = isPlaying();
1613 stop(false);
1614 openCurrentAndNext();
1615 if (wasPlaying) {
1616 play();
1617 }
1618 }
1619 notifyChange(META_CHANGED);
1620 }
1621 return last - first + 1;
1622 }
1623 }