最適化された3-Thread並列処理


これは私が書いた組織文章の移植です.

導入する


今回のキャンペーンでは、Next、Prevボタンで音楽を流すと、Viewpagerがガタガタ!

質問です。


次は、Prevコンサートを選ぶとViewpagerが遅くなりますが、コンサートが変わるので大丈夫でしょう...私は安易な考えを考えた.しかし、他の音楽プレーヤーに比べて、確かにつまずいているような気がして、原因を理解し始めました.
Viewpagerがどもる原因は
1.画像のロード
2.誤った設計
と思った.
しかし、根本的な問題はコードです.やっぱり私のせい...
Viewpagerがガタガタしている理由を理解するために、Viewpagerをブラウズしたときに実行されるコードのように、コードを注釈処理して原因を特定します.
結果!
public class PlayerController {
    // ...
    public void setMusic(final Uri musicUri) {    
        // ...        
        player = MediaPlayer.create(context, musicUri);    
        // ...
    }
    // ...
}
音楽を設定するたびにMediaPlayer.クリエイティブは音楽を作り、ここではMainThreadのリソースをたくさん使って、つまずいてしまう現象が発生しました.

解決策


したがって,対応するコードをThreadで処理し,ノッキング現象を解決した.
コードを表示する場合
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();        
    // ...
    }
    // ...
}

質問です。


このようにコードを変更すると,つまずいた現象が解決される.しかし、もっと大きな問題が発生した.
音楽をすばやく変更すると、2つの音楽を同時に実行する問題が発生します.
理由はMusicPlayerを解放する部分があるが、それはThreadで並列に処理されているため、1つのThreadが完了するまで、次のThreadが開始されると、以前の音楽は解放されない.

解決策


そこで対処法を考えながら、本やネットを探しました.
その結果、MusicPlayerを1つのThreadしかアクセスできないThread-Safe Listに入れ、最後に選択した音楽を除いて残りの部分を解放する方法が選択された.画像で確認すれば.

コードを表示する場合
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();    
    // ...
    }
    // ...
}

スクリーンショット


変更後も音楽は1つしか実行されません.
AS-ISTO-BE