使用静态var和传递对象参数之间哪一个更好?

时间:2015-10-22 09:13:25

标签: java android

我想写一个APP来记录屏幕,有两种方式,RecordHelper_Method_A和RecordHelper_Method_B。

在RecordHelper_Method_A中,我将mMediaRecorder,MediaProjection mMediaProjection和mVirtualDisplay定义为静态var,它很容易调用,例如StartRecord( mContext, requestCode, resultCode,data)StopRecord()

并且在RecordHelper_Method_B中,我需要在主Activity类中定义mMediaRecorder,MediaProjection mMediaProjection,并在调用StartRecord(mMediaRecorder, mMediaProjection,mVirtualDisplay),'StopRecord(mMediaRecorder,mMediaProjection,mVirtualDisplay)时传递参数`...,它有点复杂。

我不知道哪一个更好,而且当我结束APP时,我不知道是否可以在RecordHelper_Method_A中正确释放这些静态var。

顺便说一句,如果你有更好的方法,请告诉我吗?谢谢!

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

}

5 个答案:

答案 0 :(得分:9)

我建议Objects不要活statically。无论您创建什么对象或资源,都应该在活动消失时死亡。因此,在活动中创建这些资源然后传递它是很好的。

另外,我发现在你建议的两种方法中,这些方法本身都是静态的。最好为类创建一个对象,然后将资源传递给该对象。这可以防止意外的内存泄漏。你可以在你的Activity中做这样的事情。

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

这使事情变得简单。一旦Activity死亡,helper对象也会死亡。因此,所有资源都将被释放。

答案 1 :(得分:3)

通常,如果要使用静态函数,则不希望从外部定义静态变量。这将导致性能下降。此外,静态方法应该足以满足“自身”的可行性和维护。

由于我们处于Android环境中,您可以阅读本文以获取更多详细信息/提示:http://developer.android.com/training/articles/perf-tips.html

答案 2 :(得分:1)

依赖注入总是更好(你看到名称经典)。所以放开静态变量并寻找一种方法来提供你的方法等等。

使用这意味着更多的代码可重用性,更高的可读性,更少的对象寿命 - 当方法完成时死亡等等。

答案 3 :(得分:1)

如果建议不使用静态变量,那么为什么要引入它们。 嗨伙计们,我想这都是要通过经验学习如何使用静态变量并以有效的方式处理它们。我只是想说,只是不要把它当作使用静电可能是有害的而不是使用它们而不知道是有害的。 :)

答案 4 :(得分:1)

静态变量在不包含可变状态(即常量或只读值)时是可以的。否则它们是全局变量,因此它们的使用被认为是一种不好的做法。为什么呢?
From WikipediaEvil Static Variables

  • 降低可测试性。
  • 增加复杂性(取决于封装)
  • 名称共享(或多或少是真的,取决于语言)

如果静态行为引用唯一资源,然后不能共享和可测试(数据库,文件系统,套接字等等),那么即使是静态行为也可能会出现问题。