2017-09-12 11 views
0

私は現在、新しいバージョンを作るためにAndroidアプリを手に入れています。このアプリはアクティビティやフラグメントなしで作成されています。あなたが知っている、抽象化に熱心な人によって開発されたApp ...そこには、MortarScopeというコンセプトはどこでも使われていますが、実際の動作とその目的は何であるか分かりません。モルタル。私は文書hereがあることを知っているが、明確な説明は非常に高く評価されるだろう。Android - MortarScopeの仕組みは?

+1

検索エンジンで 'square mortar android'を検索すると、https://medium.com/square-corner-blog/simpler-android-apps-with-flow-and-mortar-5beafcd83761のようなリソースが見つかります。 https://www.bignerdranch.com/blog/an-investigation-into-flow-and-mortar/およびhttps://academy.realm.io/posts/using-flow-mortar/。質問を編集して**具体的に**あなたが理解していないことを説明したいと思うかもしれません。 – CommonsWare

答えて

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は、あなたがgetSystemService(明らかにのみローカル・レベルで)を使用してMortarScopeからサービスを得ることができるようになりますmortarScope.createContext(context)を使用して、MortarContextWrapperに配置することができるということです。

これは、ContextWrapperが階層を作成し、getSystemService()も階層ルックアップを実行するために機能します。これが意味

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

このように作成されている場合、このビューのコンテキストラッパーがMortarScopeを保存することができます

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

いるあなたは、このような何かをするとき:

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範囲によって生かされ、したがって、構成変更が内部に格納されたサービスを破壊しませんモルタルスコープ。

+0

ありがとうございました。ですから、私がよく理解すれば、MortarとMortarScopeの主な目的は、コンテキスト内でサービスをカプセル化し、getSystemServiceを通してそれらを使用できるようにすることです。 –

+0

はい、まさに!さらに、親は明示的に破壊されない限りモルタルスコープを生き残りますので、モルタルスコープ内のすべてのサービスは構成の変更を生き残ります(f.ex.回転) – EpicPandaForce