2016-07-14 7 views
1

Gibt es in Android (Java) einen Mechanismus zum Beibehalten des logischen Kontexts, ähnlich wie bei .NET ExecutionContext? Mit logischem Kontext meine ich, dass Informationen, die einmal beibehalten wurden, später über den gesamten Ausführungs-Thread zugänglich sind, was bedeutet, dass sie Async-Aufrufe überleben werden. Zum Beispiel:Flussausführung/logischer Kontext bei asynchronen Aufrufen

handler = new Handler(); 

final Runnable r = new Runnable() { 
    public void run() { 
     System.out.print(LogicalContext.get("foo")); //should print "bar" 
    } 
}; 

LogicalContext.set("foo", "bar"); 
handler.postDelayed(r, 1000); 

Um zu klären, weiß ich über Verschlüsse. Was ich jedoch brauche, ist ein automatischer Mechanismus, bei dem ich nicht den Kontext erfassen muss, den ich jedes Mal bestehen möchte. Um es weiter zu verdeutlichen, ein bloßes statisches Feld wird auch nicht funktionieren, da ich unterschiedliche logische Ausführungsabläufe unterschiedliche Kontexte haben möchte (die beginnen würden, wenn ich LogicalContext.set anrufe und [durch Kopieren] durch irgendeinen von da an ausgeführten asynchronen Anruf fließe).

In C# würde es so aussehen:

CallContext.LogicalSetData("foo", "bar"); 
await Task.Run(() => Console.WriteLine(CallContext.LogicalGetData("foo"))); 

Wenn das nicht möglich ist, würde ich für einen speziellen Fall dieses Mechanismus regeln - festzustellen, ob der aktuelle logische Fluss/Ausführungs-Thread von einem IntentService entstanden.

+1

genau das Gegenteil von http://stackoverflow.com/questions/5754281/inheritable-thread-local-in-net :) –

Antwort

1

Sie können InheritableThreadLocal<T> verwenden, die von .NET ähnlich ist AsyncLocal<T>:

Handler handler = new Handler(); 
final InheritableThreadLocal<String> foo = new InheritableThreadLocal<String>(); 

final Runnable r = new Runnable() { 
    public void run() { 
     System.out.print(foo.get()); // prints "Bar" 
    } 
}; 

foo.set("Bar"); 
handler.postDelayed(r, 1); 
+0

Nice find !!!!!! –

+0

Es ist jedoch wichtig zu beachten, dass es dem Ausführungskontext von .NET nicht vollständig entspricht. Dies gilt nur, wenn ein Thread * erstellt wird *. Wenn Sie also Arbeit an einen vorhandenen Thread delegieren (z. B. den Haupt/UI-Looper), fließt der Kontext nicht. Dies steht im Gegensatz zu dem Ausführungskontext von .NET, wo 'CallContext.LogicalSetData' auch dann fließen würde, wenn etwas wie' SynchronizationContext.Post' verwendet wird (was in UI-Frameworks wie WPF typischerweise den Delegaten an einen vorhandenen [UI] -Thread sendet). –

Verwandte Themen