Gibt es eine Möglichkeit, die aktuelle Context
Instanz innerhalb einer statischen Methode?
Ich bin auf der Suche nach dieser Möglichkeit, weil ich es hasse, die Instanz "Context" jedes Mal zu speichern, wenn sie sich ändert.
Gibt es eine Möglichkeit, die aktuelle Context
Instanz innerhalb einer statischen Methode?
Ich bin auf der Suche nach dieser Möglichkeit, weil ich es hasse, die Instanz "Context" jedes Mal zu speichern, wenn sie sich ändert.
In Kotlin, setzen Context/App Context in Companion-Objekt noch produzieren Warnung Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
oder wenn Sie etwas wie dieses verwenden:
companion object {
lateinit var instance: MyApp
}
Es ist einfach täuschen die Lint nicht das Speicherleck zu entdecken, die App-Instanz kann immer noch Speicherleck produzieren, da Application-Klasse und seine Nachkommen ein Kontext ist.
Alternativ können Sie auch funktionale Schnittstellen oder funktionale Eigenschaften verwenden, um den Kontext Ihrer Anwendung zu erhalten.
Erstellen Sie einfach eine Objektklasse:
object CoreHelper {
lateinit var contextGetter: () -> Context
}
oder Sie können es sicherer verwenden, indem Sie einen nullbaren Typ verwenden:
object CoreHelper {
var contextGetter: (() -> Context)? = null
}
und fügen Sie in Ihrer App-Klasse diese Zeile hinzu:
class MyApp: Application() {
override fun onCreate() {
super.onCreate()
CoreHelper.contextGetter = {
this
}
}
}
und deklarieren Sie in Ihrem Manifest den Namen der Anwendung zu . MyApp
<application
android:name=".MyApp"
Wenn Sie den Kontext abfragen wollen, rufen Sie einfach auf:
CoreHelper.contextGetter()
// or if you use the nullable version
CoreHelper.contextGetter?.invoke()
Ich hoffe, es hilft.
Wenn Sie die Manifestdatei nicht ändern wollen, können Sie den Kontext manuell in einer statischen Variablen in Ihrer ersten Aktivität speichern:
public class App {
private static Context context;
public static void setContext(Context cntxt) {
context = cntxt;
}
public static Context getContext() {
return context;
}
}
Und legen Sie einfach den Kontext fest, in dem Ihre Aktivität (oder Aktivitäten) beginnen:
// MainActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set Context
App.setContext(getApplicationContext());
// Other stuff
}
Nota: Wie bei allen anderen Antworten handelt es sich um ein potenzielles Speicherleck.
Selon diese Quelle können Sie Ihren eigenen Kontext erhalten, indem Sie ContextWrapper erweitern
public class SomeClass extends ContextWrapper {
public SomeClass(Context base) {
super(base);
}
public void someMethod() {
// notice how I can use "this" for Context
// this works because this class has it's own Context just like an Activity or Service
startActivity(this, SomeRealActivity.class);
//would require context too
File cacheDir = getCacheDir();
}
}
Proxying-Implementierung von Context, die einfach alle ihre Aufrufe an einen anderen Context delegiert. Kann unterklassifiziert werden, um das Verhalten zu ändern, ohne den ursprünglichen Context zu ändern.
Sie können die folgenden Möglichkeiten nutzen:
MainActivity.this.getApplicationContext();
MainActivity.java:
...
public class MainActivity ... {
static MainActivity ma;
...
public void onCreate(Bundle b) {
super...
ma=this;
...
Jede andere Klasse:
public ...
public ANY_METHOD... {
Context c = MainActivity.ma.getApplicationContext();
Wenn Sie aus irgendeinem Grund Anwendungskontext in einer beliebigen Klasse wünschen, nicht nur in solchen, die Anwendung/Aktivität erweitern, vielleicht für einige Fabrik- oder Hilfsklassen. Sie können das folgende Singleton zu Ihrer Anwendung hinzufügen.
public class GlobalAppContextSingleton {
private static GlobalAppContextSingleton mInstance;
private Context context;
public static GlobalAppContextSingleton getInstance() {
if (mInstance == null) mInstance = getSync();
return mInstance;
}
private static synchronized GlobalAppContextSingleton getSync() {
if (mInstance == null) mInstance =
new GlobalAppContextSingleton();
return mInstance;
}
public void initialize(Context context) {
this.context = context;
}
public Context getApplicationContext() {
return context;
}
}
und initialisieren Sie es dann im onCreate Ihrer Anwendungsklasse mit
GlobalAppContextSingleton.getInstance().initialize(this);
Sie können es überall verwenden, indem Sie
GlobalAppContextSingleton.getInstance().getApplicationContext()
Ich empfehle diesen Ansatz jedoch nur für den Anwendungskontext. Da es Speicherlecks verursachen kann.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.