502 Stimmen

Anwendungskontext überall verwenden?

Ist bei einer Android-App etwas falsch an der folgenden Vorgehensweise?

public class MyApp extends android.app.Application {

    private static MyApp instance;

    public MyApp() {
        instance = this;
    }

    public static Context getContext() {
        return instance;
    }

}

und ihn überall dort übergeben (z.B. SQLiteOpenHelper), wo Kontext benötigt wird (und natürlich nicht durchsickert)?

23 Stimmen

Nur um dies für andere zu verdeutlichen, können Sie dann die <application> Knoten Ihrer AndroidManifest.xml-Datei, um die folgende Attributdefinition aufzunehmen: android:name="MyApp" . MyApp muss sich unter demselben Paket befinden, auf das Ihr Manifest verweist.

0 Stimmen

Warum die Statik? Die Anwendungsinstanz ist immer vor allen anderen geschaffen. Wo immer Sie auf den Anwendungskontext zugreifen sollen, wird er Ihnen als Argument übergeben. Dieser Ansatz kann Ihre Tests verkomplizieren. Static-itis fördert die allgemeine Kopplung.

6 Stimmen

AWESOME Weg, um das Problem der Bereitstellung eines Kontextes an den SQLiteOpenHelper zu umgehen! Ich habe ein Singleton "SQLiteManager" implementiert und war bei "wie zum Teufel bekomme ich einen Kontext zu dem Singleton?" stecken.

5voto

Martin Punkte 11267

Das ist ein guter Ansatz. Ich verwende ihn auch selbst. Ich würde nur vorschlagen, Folgendes außer Kraft zu setzen onCreate um das Singleton zu setzen, anstatt einen Konstruktor zu verwenden.

Und da Sie erwähnt haben SQLiteOpenHelper : Unter onCreate () können Sie auch die Datenbank öffnen.

Ich persönlich denke, dass die Dokumentation falsch liegt, wenn sie sagt, dass Normalerweise ist es nicht notwendig, die Unterklasse Application . Ich denke, das Gegenteil ist der Fall: Sie sollten Application immer unterklassifizieren.

3voto

Blundell Punkte 72729

Ich würde Anwendungskontext verwenden, um einen Systemdienst im Konstruktor zu erhalten. Dies erleichtert das Testen und profitiert von der Komposition

public class MyActivity extends Activity {

    private final NotificationManager notificationManager;

    public MyActivity() {
       this(MyApp.getContext().getSystemService(NOTIFICATION_SERVICE));
    }

    public MyActivity(NotificationManager notificationManager) {
       this.notificationManager = notificationManager;
    }

    // onCreate etc

}

Die Testklasse würde dann den überladenen Konstruktor verwenden.

Android würde den Standardkonstruktor verwenden.

1voto

Franklin Peña Punkte 43

Ich mag es, aber ich würde stattdessen ein Singleton vorschlagen:

package com.mobidrone;

import android.app.Application;
import android.content.Context;

public class ApplicationContext extends Application
{
    private static ApplicationContext instance = null;

    private ApplicationContext()
    {
        instance = this;
    }

    public static Context getInstance()
    {
        if (null == instance)
        {
            instance = new ApplicationContext();
        }

        return instance;
    }
}

0voto

Seraphim's Punkte 12072

Ich verwende den gleichen Ansatz, ich schlage vor, das Singleton ein wenig besser zu schreiben:

public static MyApp getInstance() {

    if (instance == null) {
        synchronized (MyApp.class) {
            if (instance == null) {
                instance = new MyApp ();
            }
        }
    }

    return instance;
}

aber ich benutze nicht überall, ich benutze getContext() y getApplicationContext() wo ich es tun kann!

0voto

Stanley Ko Punkte 2930

Ich weiß, dass die ursprüngliche Frage vor 13 Jahren gepostet wurde, und dies ist die Kotlin-Version von überall Kontext zu bekommen.

class MyApplication : Application() {
    companion object {
        @JvmStatic
        private var instance: MyApplication? = null

        @JvmStatic
        public final fun getContext(): Context? {
            return instance
        }
    }

    override fun onCreate() {
        instance = this
        super.onCreate()
    }
}

CodeJaeger.com

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.

Powered by:

X