Android - MortarScope如何运作?

时间:2017-09-12 16:49:20

标签: android mortar

我目前正在拿一个Android应用程序来制作它的新版本。该应用程序是在没有活动或碎片的情况下制作的。你知道,一个由抽象热情的人开发的应用程序......在那里, MortarScope 的概念在任何地方都被使用,但实际上无法弄清楚它是如何工作的以及什么是目的,以及 迫击炮 。我知道有文件here,但我们将非常感谢明确的解释。

1 个答案:

答案 0 :(得分:0)

MortarScope是一个Map<String, Object>,可以拥有它继承的父级。

// vague behavior mock-up
public class MortarScope {
     Map<String, Object> services = new LinkedHashMap<>();
     MortarScope parent; 

     Map<String, MortarScope> children = new LinkedHashMap<>();

     public MortarScope(MortarScope parent) {
         this.parent = parent;
     }

     public boolean hasService(String tag) {
         return services.contains(tag);
     }

     @Nullable
     public <T> T getService(String tag) {
         if(services.contains(tag)) { 
             // noinspection unchecked
             return (T)services.get(tag);
         }
         if(parent == null) {
             return null;
         }
         return parent.getService(tag);
     }
}

棘手的是MortarScope可以使用MortarContextWrapper放入mortarScope.createContext(context),这样您就可以使用getSystemService从MortarScope获取服务了(显然只在本地级别。)

这是有效的,因为ContextWrapper创建了一个层次结构,而getSystemService()也进行了层次查找。

class MortarContextWrapper extends ContextWrapper {
  private final MortarScope scope;

  private LayoutInflater inflater;

  public MortarContextWrapper(Context context, MortarScope scope) {
    super(context);
    this.scope = scope;
  }

  @Override public Object getSystemService(String name) {
    if (LAYOUT_INFLATER_SERVICE.equals(name)) {
      if (inflater == null) {
        inflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
      }
      return inflater;
    }
    return scope.hasService(name) ? scope.getService(name) : super.getSystemService(name);
  }
}

这可以使View的上下文包装器存储MortarScope如果它是这样创建的

LayoutInflater.from(mortarScope.createContext(this)).inflate(R.layout.view, parent, false);

这意味着当你做这样的事情时:

public class MyService {
    public static MyService get(Context context) {
         // noinspection ResourceType
         return (MyService)context.getSystemService("MY_SERVICE");
    }
}

public class MyView extends View {
    ...
    MyService myService = MyService.get(getContext());

然后,您可以通过跨上下文(视图,活动,应用程序)的层次查找强制getSystemService()从您上方的任何级别获取MyService

除非明确销毁,否则父级会保留子级,因此Activity范围由Application范围保持活动状态,View范围由Activity保持活动状态范围,因此配置更改不会破坏存储在MortarScope中的服务。