单例设计模式在Android开发实际应用场景解析–activity的管理

单例设计模式在Android开发实际应用场景解析–activity的管理

Android中实际场景

常用的场景都是一些特殊的类,比如,管理类,皮肤的管理,activity的管理。

1.1 介绍

客户端调用单例类。

思路:

  1. 构造函数私有化。
  2. 通过静态方法获取单例对象。客户端调用
  3. 多线程环境下确保对象只有一个。
  4. 反序列化不能重新构造新对象。
1.1.1 懒汉模式

声明一个静态对象,第一次调用就初始化。

public class Singleton {
    private static Singleton instance;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

我们加上synchronized关键字,这样就可以做到线程的同步,在多线程环境下保证单例。懒汉式在第一次调用的时候才会实例化,节约资源,缺点是同步方法的调用造成资源开销。

1.1.2 DCL单例

需要时才实例化单例,保证线程安全,并且没有同步锁开销。

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

getInstance()方法中我们判空两次,第一次是避免每次调用都进行同步锁,第二次是在null的条件下创建实例对象。

分析:

假设A,B两个线程执行getInstance(),instance = new Singleton();这句代码会被翻译成多条汇编指令,

  1. 分配内存。
  2. 调用构造函数。
  3. 将引用指向内存空间。

在多线程的环境下,这三个步骤的执行顺序不一样会导致DCL失效,执行顺序有可能1,2,3,或者1,3,2。在3执行完,2没执行之前,切换到B线程,这时候线程A执行了3,instance已经非空,B线程获取instance已经非空,就会出错。

1.1.3 volatile关键字
  1. 防止重排序。
  2. 线程可见性–某一个线程改变了公用对象(变量),短时间内可能是不可见的,每一个线程都有自己的缓冲区,线程工作区,
public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            } 
        }
        return instance;
    }
}
1.1.4 静态内部类

第一次加载Singleton类不会实例化对象,第一次调用getInstance才会导致被初始化,第一次调用getInstance()导致SingletonHolder加载,可以保证线程安全,对象唯一,延迟实例化。

public class Singleton {

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.sInstance;
    }

    private static class SingletonHolder {
        private static final Singleton sInstance = new Singleton();
    }
}
1.1.5 容器单例模式

Android系统服务用的这种

public class Singleton {
    private static Map<String, Object> mSingleton = new HashMap<>();

    static {
        mSingleton.put("activity_manager", new Singleton());
    }

    public static Object getService(String serviceName) {
        return mSingleton.get(serviceName);
    }
}

Android实际应用–Activity的管理

需求背景:当我们有很多个activity的时候,需要写一个管理类来操作它们的增删改查。

xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activity.DebugActivity">

    <TextView
        android:onClick="click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text"
        android:textSize="30sp" />


</LinearLayout>

ActivityManager管理类

public class ActivityManager {
    private static ActivityManager mInstance;
    private Stack<Activity> mActivities;

    private ActivityManager() {
        mActivities = new Stack<>();
    }

    public static ActivityManager getInstance() {
        if (mInstance == null) {
            synchronized (ActivityManager.class) {
                if (mInstance == null) {
                    mInstance = new ActivityManager();
                }
            }
        }
        return mInstance;
    }

    public void attach(Activity activity) {
        mActivities.add(activity);
    }

    public void detach(Activity detachActivity) {
        for (Activity activity : mActivities) {
            if (activity == detachActivity) {
                mActivities.remove(activity);
            }
        }
    }

    public void finish(Activity finishActivity) {
        for (Activity activity : mActivities) {
            if (activity == finishActivity) {
                mActivities.remove(activity);
                activity.finish();
            }
        }
    }

    public void finish(Class<? extends Activity> finishClassActivity) {
        for (Activity activity : mActivities) {
            if (activity.getClass().getCanonicalName().equals(finishClassActivity.getCanonicalName())) {
                mActivities.remove(activity);
                activity.finish();
            }
        }
    }
    public Activity currentActivity() {
        return mActivities.lastElement();
    }
}

LoginActivity

public class LoginActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityManager.getInstance().attach(this);
        setTitle("我是LoginActivity");
    }

    public void click(View view) {
        Intent intent = new Intent(this, RegisterActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityManager.getInstance().detach(this);
    }
}

RegisterActivity

public class RegisterActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityManager.getInstance().attach(this);
        setTitle("我是RegisterActivity");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityManager.getInstance().detach(this);
    }

    public void click(View view) {
        ActivityManager.getInstance().finish(this);
        ActivityManager.getInstance().finish(LoginActivity.class);

    }
}

DebugActivity

class DebugActivity : AppCompatActivity() {
    private val TAG = javaClass.simpleName
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        ActivityManager.getInstance().attach(this)
        title = "我是DebugActivity"
    }

    fun click(view: View) {
        val intent = Intent(this, LoginActivity::class.java)
        startActivity(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityManager.getInstance().detach(this)
    }
}

不管以哪种形式实现单例模式,
它们的核心原理都是将构造函数私有化,
并且通过静态方法获取一个唯一的实例,
在这个获取的过程中须保证线程安全、
防止反序列化导致重新生成实例对象等问题。
选择哪种实现方式取决于项目本身,
如是否是复杂的并发环境、JDK 版本是否过低、单例对象的资源消耗等。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android源码设计模式解析与实践是一本关于Android系统中的设计模式的书籍,旨在通过解析Android源码中的实际案例来理解和应用设计模式Android系统是一个庞大而复杂的开源项目,其中包含了大量的设计模式。这些设计模式不仅帮助Android系统实现了高效、稳定、易于扩展的特性,也可以为Android开发者提供参考和借鉴的经验。 本书首先介绍了设计模式的概念和基本原理,包括单例模式、工厂模式、观察者模式、策略模式等。然后,结合Android源码中的具体实例,详细讲解了这些设计模式Android系统中的应用场景和实践方法。 例如,书中通过分析Android系统中的Activity、Fragment、View等核心组件的源码,解析了它们是如何应用观察者模式和状态模式来实现界面更新和事件传递的。又如,书中通过分析Android系统中的Handler、Looper、MessageQueue等核心类的源码,讲解了它们是如何应用责任链模式来实现线程间通信和消息处理的。 此外,本书还探讨了Android系统中的一些特殊设计模式,如MVC模式、MVP模式、MVVM模式等,帮助读者理解和应用这些模式来构建更加优雅和可维护的Android应用程序。 总之,通过学习和实践本书中介绍的Android源码设计模式,读者可以更深入地了解Android系统的设计原则和实践经验,提升自己的Android开发技能,并能够更加高效地开发出高质量的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值