【Android-设计模式】单例模式

有哪些单例模式:

  • 线程内
  • 线程间
  • 进程间

普通单例:

【实现方式1】:双重确认–Double Check Lock(DCL)

class Singleton {
  private static Singleton sInstance = null;
  private Singleton(){
  }
  public void doSomething(){
    Ststen,iyt,orubtkb*:di sth.");
  }

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

为了减少重复代码,可用泛型来优化:

//抽象一个通用的单例
public abstract class Singleton<T>{
  private volatile T mInstance;

  //抽象具体的创建方法
  protected abstract T create();
  
  public final T get(){
    if(mInstance == null){
      synchronized(this){
        if(mInstance == null){
          mInstance = create();
        }
      }
    }
  }
}

//Singleton 创建一个单例,并实现其create方法
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>(){
  protected IActivityManager create(){
    IBinder b = ServiceManager.getService("activity");
    IActivityManager am = asInterface(b);
    return am;
  }
};

//封装获取IActivityManager单例的函数:
static public IActivityManager getDefault(){
  //获取真正的单例对象
  return gDefault.get();
}

【实现方式2】:静态内部类单例

public class Singleton {
  private Singleton(){}
  public static Singleton getInstance(){
    return SingletonHolder.sInstance;
  }
  //静态内部类:
  private static class SingletonHolder{
    private static final Singleton sInstance = new Singleton();
  }
}

【实现方式3】:使用容器

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

  private SingletonManager(){}
  publict static void registerService(String key, Object instance) {
    if (!objMap.containsKey(key)){
      objMap.put(key, instance);
    }
  }

  public static Object getService(String key) {
    return objMap.get(key);
  }
}

线程内的单例:

private static final ThreadLocal<Choreographer> sThreadInstance = 
  new ThreadLocal<Choreographer>(){
    @Override
    protected Choreographer initialValue(){
      Looper looper = Looper.myLooper();
      return new Choreographer(looper);
    }
};

public static Choreographer getInstance(){
  return sThreadInstance.get();
}

ThreadLocal 在同一个线程中获得同一个对象,不同线程中获得不同对象

进程间单例:

所有进程中只有一个实例,其实现需要一个中间人
例如:ServiceManager,其中间人是binder驱动。

int main(int argc, char **argv){
  struct binder_state *bs;
  bs = binder_open(128*1024);
  binder_become_context_manager(bs);
  ......
}

//驱动中的逻辑:
case BINDER_SET_CONTEXT_MGR:
  if(binder_context_mgr_node != NULL){
    //如何已经MGR已经注册,则报错
    pr_err("BINDER_SET_CONTEXT_MGR already set\n");
    ret = -EBUSY;
    goto err;
  }
  //生成mgr结点
  binder_context_mgr_node = binder_new_node(proc, 0, 0);

//每个进程都有:
private static IServiceManger getIServiceManager(){
  if(sServiceManager != null){
    return sServiceManager;
  }
 
  sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
  return sServiceManager;
}

//对所有进程来说,ServiceManager对应的binder句柄都是同一个:0号binder
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){
  return getStrongProxyForHandle(0);
}
发布了114 篇原创文章 · 获赞 27 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/menghaocheng/article/details/104405248
今日推荐