Home » Android » java – Which one is the better between using static var and passing object parameter?

java – Which one is the better between using static var and passing object parameter?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I want to write an APP to record screen, there are two way, RecordHelper_Method_A and RecordHelper_Method_B .

In RecordHelper_Method_A, I define mMediaRecorder, MediaProjection mMediaProjection and mVirtualDisplay as static var, it’s easy to invoke, such as StartRecord( mContext, requestCode, resultCode,data), StopRecord().

and in RecordHelper_Method_B, I need to define mMediaRecorder, MediaProjection mMediaProjection in main Activity class, and pass the parameters when I invoke StartRecord(mMediaRecorder, mMediaProjection,mVirtualDisplay), ‘StopRecord(mMediaRecorder,mMediaProjection,mVirtualDisplay)`…, it’s a little complex.

I don’t know which one is the better, and more I don’t know if these static var can be released correctly in RecordHelper_Method_A when I end the APP.

BTW, if you have the better way, would you please tell me ? Thanks!

RecordHelper_Method_A

public class RecordHelper_Method_A {

    private static MediaRecorder mMediaRecorder;
    private static MediaProjection mMediaProjection;
    private static VirtualDisplay mVirtualDisplay;

    public static void StartRecord(Context mContext,int requestCode, int resultCode, Intent data){

        mMediaRecorder = new MediaRecorder();
        initRecorder();

        MediaProjectionManager mProjectionManager = (MediaProjectionManager) mContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);

        mVirtualDisplay=mMediaProjection.createVirtualDisplay("MainActivity",
                400,600, 300,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mMediaRecorder.getSurface(), null, null);

        MediaProjectionCallback mMediaProjectionCallback = new MediaProjectionCallback();
        mMediaProjection.registerCallback(mMediaProjectionCallback, null);

        mMediaRecorder.start();
    }

    public static void StopRecord(){
        mMediaProjection=null;
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mVirtualDisplay.release();
    }


    private static void initRecorder() {
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        //...
    }

    private static class MediaProjectionCallback extends MediaProjection.Callback {
        @Override
        public void onStop() {
            mMediaRecorder.stop();
        }
    }
}

RecordHelper_Method_B

public class RecordHelper_Method_B {

    public static void StartRecord(MediaRecorder mMediaRecorder,MediaProjection mMediaProjection,VirtualDisplay mVirtualDisplay){

        initRecorder(mMediaRecorder);

        mVirtualDisplay=mMediaProjection.createVirtualDisplay("MainActivity",
                400,600, 300,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mMediaRecorder.getSurface(), null, null);

        MediaProjectionCallback mMediaProjectionCallback = new MediaProjectionCallback(mMediaRecorder);
        mMediaProjection.registerCallback(mMediaProjectionCallback, null);

        mMediaRecorder.start();
    }

    public static void StopRecord(MediaRecorder mMediaRecorder,MediaProjection mMediaProjection,VirtualDisplay mVirtualDisplay){
        mMediaProjection=null;
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mVirtualDisplay.release();
    }


    private static void initRecorder(MediaRecorder mMediaRecorder) {
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        //...
    }

    private static class MediaProjectionCallback extends MediaProjection.Callback {
        MediaRecorder mMediaRecorder;
        public MediaProjectionCallback(MediaRecorder mMediaRecorder){
            this.mMediaRecorder=mMediaRecorder;
        }

        @Override
        public void onStop() {
            mMediaRecorder.stop();
        }
    }

}
How to&Answers:

I would suggest Objects not living statically. Whatever object or resource that you create, should die when the activity dies. So creating these resources in the activity and then passing it is good.

Also, I see that in both of the methods that you suggested, the methods are themselves static. It’s better to create an object for the class and then pass the resources to this object. This would prevent accidental memory leaks. You could do something like this in your Activity.

RecordHelper_Method_B helper = new RecordHelper_Method_B ();
helper.StopRecord(mMediaRecorder,mMediaProjection,mVirtualDisplay);

This keeps things simple. Once your Activity dies, so will the helper object. So all resources will be released for sure.

Answer:

In general, if you want to use static functions, you should prefer to not define static variables from outside. It will result in a degradation of the performances. Also, a static method should be sufficent by “itself” for lisibility and maintenance.

As we are in Android context, you can read this article for further details/tips : http://developer.android.com/training/articles/perf-tips.html

Answer:

Dependency Injection is better all the time (you see the name classic). so let go of the static variables and look for a way to feed your methods etc etc.

using this means more re-usability of your code, more readability, less lifespan of objects-as they die when method is done etc etc.

Answer:

If static variables are suggested not be used then why were they introduced.
Hi guys, I guess it’s all about to learn by experience that how to use static variables and handle them in effective way. I only want to say that just don’t take it as using static can be harmful rather using them without knowing is harmful. 🙂

Answer:

Static variables are ok when they don’t contains mutable state (ie constants or readonly values). Otherwise they are global variables and as such their usage is considered as a bad practice. Why?
From Wikipedia or the Evil Static Variables :

  • Decrease testability.
  • Increases complexity (depends on encapsulation)
  • Name sharing (more or less true, depends on languages)

Even static behaviour could be problematic if it refers to unique resources and then not share-able and testable (database, file system, sockets, etc…)