Dynamic UI Progress Updates using Interface + ExecutorService Issue

So I have a music application. I am trying to update the UI with the progress of the media player (like current time, current song, album cover) everytime the song changes. I found that using interfaces was a awesome magical way of communication between activity and fragments so I implemented an interface in my MusicManger class. My code will show what and how did it.

Two problems

1) Commented look below, ExecutorService seems to stop after one loop. No Errors in catch block (this is why I tagged with java)

2) Commented please look, All the System.out methods print but the UI doesn't update. I do believe I called the method from mainThread so it should update.

I'll show code in logical order will add titles in bold before code segment to tell you basic idea of code.

Passing UI references from fragment to MusicManager class, code below in Fragment class

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;
}

As Commended above the code that is located in MusicManager class that takes references and stores them. Also shows interface implementation with MusicManager class. And the Executor service

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);
}

Finally some code from MainActivity class that actually is suppose to update the UI note that both println's work as expected but only once as stated above because of the executorservice issue

  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();
}

The view array is shown perviously! Also the last view in the array is shown as the main view for songlist fragment.

I am sorry for all the code I've tried to debug it as you can see from my println's there is just something I am unaware of going on here.

Answers


Ok so there was an error that I needed to catch to see within the following code:

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();
}

The issue is I was trying to change the view from a different thread then the one which created it. Solving it was pretty long and painful but basically I made it nonstactic used more interfaces then used the famous

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


Need Your Help

Different resolutions for the same media query on the same website on the same device?

html css media-queries blackberry-10

I have a problem with automatically changing resolution on Blackberry Playbook 7" and Blackberry Q10 (720 x 720) on some pages on a website I'm currently working on. The problem is illustrated on