在Android studio 中使用單例模式


本篇簡單介紹如何在Android studio中 使用單例模式和使用注意事項。

單例模式

為什么要使用單例模式?

有一些對象我們只需要一個,只需要一個線程池 、緩存或是只有一台打印機、機器人 、機器人上面只有一個尋磁傳感器。我們可以通過全局的靜態變量來實現,但是全局變量在程序一開始就創建 可能比較耗費資源、可能一直沒用到。單例模式和全局變量一樣方便又沒有它的缺點。

單利模式使用


public class Sensor {

    // 使用靜態變量記錄唯一的實例
    private static Sensor sensorInstance;

    /**
     * 私有的構造方法
      */
    private Sensor(){}

    /**
     * 實例化方法
     * @return Sersor
     * synchronized包住不會有兩個線程同時進入
     */
    public static synchronized Sensor getSersorInstance(){
        if(sensorInstance == null) {
             sensorInstance = new Sensor();
        }
        // 返回Sensor唯一實例
        return sensorInstance;
    }

}

但是如果想要很急切的創建示例,而且在示例創建方面的負擔不繁重。

public class Sensor {

    private static Sensor sensorInstance = new Sensor();

    private Sensor(){}

    public static Sensor getSersorInstance(){
        return sensorInstance;
    }
}

如果有很多線程頻繁的使用getSersorInstance可能就影響性能,可以使用雙重檢查加鎖


public class Sensor {

    // volatile 保證 sensorInstance 被初始化 多個線程正確的處理
    private volatile static Sensor sensorInstance;
    
    private Sensor(){}
    
    public static Sensor getSersorInstance(){
        // 檢查 sensorInstance是否存在 如果不存在就進入同步區塊
       
        if(sensorInstance == null) {
            // 同步區塊里面的代碼只有在第一次才會執行
            synchronized(Sensor.class) {
                if(sensorInstance == null) {
                    sensorInstance = new Sensor();
                }
            }
        }
        return sensorInstance;
    }

}

Android 中使用內存泄漏問題

1.在實例化的時候我們經常需要傳入一些參數 比如說 Context

然后順利成章的


Sensor sensor = Sensor.getSersorInstance(MainActivity.this);

然后出現了一個很嚴重的問題Sensor單例持有了MainActivitythis對象,所以當我們轉跳其他Activity頁面的時候MainActivity 的對象仍然得不到釋放不能被回收。

所以我們應該使用Application中的 context

2.同樣在急切的方法中


public class Sensor {

        public static final Sensor SENSOR_INSTANCE = new Sensor();
        private List<MyListener> mListenerList;

        private Sensor() {
            mListenerList = new ArrayList<MyListener>();
        }

        public static Sensor getInstance() {
            return SENSOR_INSTANCE;
        }

        public void registerListener(MyListener listener) {
            if (!mListenerList.contains(listener)) {
                mListenerList.add(listener);
            }
        }
        public void unregisterListener(MyListener listener) {
            mListenerList.remove(listener);
        }
    }

    interface MyListener {
        public void onSomeThingHappen();
    }

MainActivity:


public class MainActivity extends Activity {

        private MyListener mMyListener=new MyListener() {
            @Override
            public void onSomeThingHappen() {
            }
        };

        private Sensor sensor = Sensor.getInstance();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            sensor.registerListener(mMyListener);
        }
}


非靜態的內部類(Sensor)的對象(mListenerList)都是會持有指向外部類對象(mMyListener)的引用。因此外部類對象(mMyListener)被持有了 同樣的不會被回收,內存泄漏,所以需要


@Override
    protected void onDestroy() {
        Sensor.unregisterListener(mMyListener);
        super.onDestroy();
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM