【问题标题】:Dynamic UI Progress Updates using Interface + ExecutorService Issue使用 Interface + ExecutorService 问题的动态 UI 进度更新
【发布时间】:2015-05-06 21:15:46
【问题描述】:

所以我有一个音乐应用程序。每次歌曲更改时,我都会尝试使用媒体播放器的进度(如当前时间、当前歌曲、专辑封面)更新 UI。我发现使用接口是在 Activity 和 Fragment 之间进行通信的一种很棒的神奇方式,所以我在我的 MusicManger 类中实现了一个接口。我的代码将显示它是什么以及如何做到的。

两个问题

1) 评论如下,ExecutorService 似乎在一个循环后停止。 catch 块中没有错误(这就是我用 java 标记的原因)

2) 评论请看,所有 System.out 方法都会打印,但 UI 不会更新。我相信我从 mainThread 调用了该方法,因此它应该更新。

我将按逻辑顺序显示代码,将在代码段之前添加粗体标题,以告诉您代码的基本概念。

将 UI 引用从片段传递到 MusicManager 类,片段类中的代码如下

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_item_songlist, container, false);

    // Set the adapter

    TextView musicManagerSongName, musicManagerCurrent, musicManagerTotal;
    ProgressBar musicManagerProgress;
    ImageView musicManagerImageView;
    mListView = (AbsListView) view.findViewById(R.id.slist);
    musicManagerSongName = (TextView)view.findViewById(R.id.textView12);
    musicManagerCurrent = (TextView)view.findViewById(R.id.textView10);
    musicManagerTotal = (TextView)view.findViewById(R.id.textView11);
    musicManagerProgress = (ProgressBar)view.findViewById(R.id.progressBar);
    musicManagerImageView = (ImageView)view.findViewById(R.id.imageView2);

    MainActivity.mediaPlayer.passUIReferences(musicManagerSongName, musicManagerCurrent, musicManagerTotal, musicManagerProgress, musicManagerImageView, view);

// line above is a method within MusicManager that takes the references will show code next!

    ImageButton playbutton = (ImageButton)view.findViewById(R.id.playbuttonbar);
    ImageButton nextButton = (ImageButton)view.findViewById(R.id.nextbuttonbar);
    ImageButton backButton = (ImageButton)view.findViewById(R.id.backbuttonbar);
    ImageButton toggleButton = (ImageButton)view.findViewById(R.id.shufflebuttonbar);
    ImageButton pausebutton = (ImageButton)view.findViewById(R.id.pausebuttonbar);
    playbutton.setBackgroundResource(R.drawable.playbuttonbar);
    playbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                MainActivity.mediaPlayer.stateChange(1);
            }catch(Exception e) {

            }
        }
    });
    backButton.setBackgroundResource(R.drawable.backbutton1);
    nextButton.setBackgroundResource(R.drawable.nextbutton1);
    toggleButton.setBackgroundResource(R.drawable.shufflebuttonselected);
    pausebutton.setBackgroundResource(R.drawable.pausebutton1);
    pausebutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                MainActivity.mediaPlayer.stateChange(0);
            } catch (Exception e){

            }
        }
    });
    mListView.setAdapter(mAdapter);
    ((MainActivity) mListener).restoreActionBar();

    return view;
}

如上所述,位于 MusicManager 类中的代码获取引用并存储它们。还显示了 MusicManager 类的接口实现。以及 Executor 服务

public void passUIReferences(View... views) {
    this.uiElements = views;
}

 private ExecutorService executorService = Executors.newSingleThreadExecutor();
private MediaplayerUpdateInterface uiUpdateInterface;

public MediaPlayerManager(MediaplayerUpdateInterface inter) {
    this.player = new MediaPlayer();
    this.uiUpdateInterface = inter;

// The below line starts the single thread while loop for excutorservice and only loops and prints "this" once after I start one song then it never loops again
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            while(true) {
                if (player.isPlaying() && uiElements != null) {
                    System.out.println("this");
                    uiUpdateInterface.updateUI(uiElements, 0);
                }
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    });
}

public interface MediaplayerUpdateInterface {
    public void updateUI(View[] views, int type);
}

最后,来自 MainActivity 类的一些代码实际上应该更新 UI 请注意,两个 println 都按预期工作,但由于 executorservice 问题,只能按上述方式工作一次

  public static MediaPlayerManager mediaPlayer = new MediaPlayerManager(new MediaPlayerManager.MediaplayerUpdateInterface() {
    @Override
    public void updateUI(View[] views, int type) {
        System.out.println("check1 " + type);
        updateMediaplayerViews(views, type);
    }
});

private static void updateMediaplayerViews(View[] views, int type)
{
    switch(type) {
        case 0:
            System.out.println("that?");
            ((TextView)views[0]).setText(mediaPlayer.getCurrentSongInfo().getName().length() > 22? mediaPlayer.getCurrentSongInfo().getName().substring(0, 19)+"..." : mediaPlayer.getCurrentSongInfo().getName());
            break;
    }
    views[views.length - 1].invalidate();
}

视图数组显示在前面!数组中的最后一个视图也显示为歌曲列表片段的主视图。

对于我尝试调试它的所有代码,我很抱歉,正如您从我的 println 中看到的那样,这里有一些我不知道的事情。

【问题讨论】:

    标签: java android executorservice


    【解决方案1】:

    好的,我需要在以下代码中捕捉到一个错误:

    private static void updateMediaplayerViews(View[] views, int type)
    {
    switch(type) {
        case 0:
            System.out.println("that?");
            ((TextView)views[0]).setText(mediaPlayer.getCurrentSongInfo().getName().length() > 22? mediaPlayer.getCurrentSongInfo().getName().substring(0, 19)+"..." : mediaPlayer.getCurrentSongInfo().getName());
            break;
    }
    views[views.length - 1].invalidate();
    }
    

    问题是我试图从另一个线程更改视图,然后是创建它的线程。解决它是相当漫长和痛苦的,但基本上我使用了更多的接口,然后使用了著名的接口。

    Mainactivity.runOnUiThread(new Runnable(....));

    【讨论】:

      猜你喜欢
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多