简体   繁体   中英

Android - Java - Access private variable in Main-Activity from another instanced class

I've been thinking for hours about this problem now without finding a solution. Still I think I'm just overlooking some very simple things.

My program is (mainly) supposed to record and playback audio, so I got one Main-Activity which contains all the functions with interactivity to the user and I got one class I called 'AudioHandler' to manage all the audio stuff in the background. The Main-Activity uses an instance of AudioHandler.

Within the AudioHandler-class I got an OnCompletionListener, to notice when playback of the recorded audio-file has finished.

The problem is: When playback has finished - and the OnCompletionListener gets called, I want to change an ImageView (Turn the pause-button into a play-button) in the Main-Activity.

How can I access the ImageView in the Main-Activity from the AudioHandler-Instance?

...without making the ImageView-Variable public.

Method that calls play from the AudioHandler in the Main-Activity:

  public State playRecording() {
    //change play-button to stop-button
    iPlay.setImageResource(R.drawable.stop_button_active);

    //start or resume playback of the recorded Audio
    ah.play();

    //Return that the program is in playing-mode
    return State.PLAYING;
}

play-function in AudioHandler

  public void play() {
        try {

            mPlayer.start();
        } catch (IllegalArgumentException e) {
            Log.d("MEDIA_PLAYER", e.getMessage());
            e.printStackTrace();
        } catch (IllegalStateException e) {
            Log.d("MEDIA_PLAYER", e.getMessage());
            e.printStackTrace();
        }




        //add listener to notice when the end of the audio record has been reached 
        mPlayer.setOnCompletionListener(new OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

                //should somehow change the ImageView 'iPlay' in the Main-Activity when reaching this point.



            }
        });     
    }

Any help is appreciated :)

Marco

If you need to gain access to a variable, that variable should be either package-accessible or public. Or, even better, you should have an encapsulating method. Something like:

// On the main class:
public ImageView getIPlay(){
    return iPlay;
}
private static MainActivity instance;
public MainActivity getInstance(){
    return instance;
}

/** Either on the constructor or the 'OnCreate' method, you should add: */
    instance = this;

Now you can access the ImageView from any Activity or class with:

   MainActivity.getInstance().getIPlay();

It's that simple, really. You can go through a lot of other solutions, from using reflection through AOP or any kind of things. But it's just making the issue more complex. Try creating the setter method.

Your question is about object encapsulation.

When you define an instance variable as private, you are saying that only that object and members of that class can access the variable. This is a good thing because it protects you from accidentally changing data you did not want to. This is also why we have getters and setters.

So in your class you have something I imagine looks like this

    public class Main {
... some code here
    private ImageView myView;
... more code here

what you need to do is add the following methods to your Main class

public ImageView getView() {
       return myView;
}

and

public void setView(ImageView a) {
       myView = a;
}

so now when you want to access the ImageView from another class, you just call something like Main.getView() and you'll have it.

Now if this doesn't answer your question, it's because you didn't design your app too thoughtfully (so it seems) but luckily I won't be the kind of responder who tells you to uproot everything you have done and start over.

It sounds like you're working with an Android app and your issue is to communicate between activities.

This is why Android has something called Intents. You can send an Intent from one activity to another to carry data. So in this case you would send an Intent from one activity to the main class that would tell the main class to change the picture in the imageview. I won't lie, I suck at using intents but there are many wonderful tutorials online that will show you how to do this.

Another option would be to create a RemoteView of your layout that has the play/pause button and access it from the other activity, RemoteView has a built in function to change the bitmap of a remote imageview (again, see the Android Developer Documentation for RemoteView for more on this)

I'm sorry I couldn't give you some actual code, I'm not confident enough in my abilities on these topics but I'm 100% confident that one of the three methods I just listed will answer your question.

You could create a public wrapper method within your main Activity that toggles the ImageView between Pause and Play.

Or, you could pass the the ImageView to the AudioHandler (via the constructor?) and just manipulate it there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM