0

我目前正在使用一个 Android 应用程序来制作它的新版本。该应用程序没有活动或片段。你知道,一个由对抽象充满热情的人开发的应用程序......在那里,MortarScope的概念无处不在,但真的无法弄清楚它是如何工作的,以及Mortar的目的是什么。我知道这里有文档但非常感谢您提供清晰的解释。

4

1 回答 1

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

棘手的是 aMortarScope可以放入 a MortarContextWrapper, using mortarScope.createContext(context),这将允许您从 MortarScope using 获取服务getSystemService(显然仅在本地级别)。

这是有效的,因为ContextWrappers 创建了一个层次结构,并且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 的上下文包装器存储 aMortarScope如果它是这样创建的

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 内的服务。

于 2017-09-12T17:07:36.493 回答