Androidアプリケーションクラスを拡張する理由


168

拡張Applicationクラスは、グローバル変数を宣言できます。他の理由はありますか?


これは頭​​に浮かんだアイデアですが、onCreateをオーバーライドして、MainActivityではなく、1回限りの起動画面、つまりユーザーが初めてアプリを開いたときに紹介画面を表示できるはずです。
btse 2013

回答:


29

オフハンドでは、アプリケーションの拡張が別のアプローチよりも望ましい、または何かを達成するために必要であるという実際のシナリオは考えられません。高価で頻繁に使用されるオブジェクトがある場合は、オブジェクトが現在存在しないことを検出したときに、IntentServiceで初期化できます。アプリケーション自体はUIスレッドで実行されますが、IntentServiceは独自のスレッドで実行されます。

明示的なインテントを使用してアクティビティからアクティビティにデータを渡すか、SharedPreferencesを使用することを好みます。インターフェースを使用して、フラグメントから親アクティビティにデータを渡す方法もあります。


39
アプリケーションクラスの拡張には多くの用途があります。非常に便利なのは、アプリケーションでキャッチされなかったすべての例外をキャッチすることです。SOこれは非常に便利なものです
png

3
どうやってやるの?
serj 2015年

8
の+1 "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences"。我々は常に我々はできる限りグローバル状態を解消し、静的/シングルトンとなどをvarsの代わりにグローバルな状態管理のための標準的なAndroidのツールを使用する必要があります
オレクサンドルKaraberov

9
どうして?意図的に制限されている間、ある時点でそれらを異なるプロセスで実行したり、任意のアプリで再利用可能なすべてのコンポーネントを準備したりするには データオブジェクトをシリアル化する代わりに渡すだけで、CPUとメモリを節約できます。内部プロセスが同じデバイスのハンドオーバー用にデータを分割することは、決して理想的ではありません。私はそのようなintentserviceの使用のポイントを実際には見ていません(他のスレッドをnewで実行するだけです)。プログラマーを混乱させるものの多くは、Googleが追加した「ヘルパー」のほとんどすべてが、アクティビティが別のコンピューターで実行されているかのように作成されていることに起因しています。
Lassi Kinnunen

127

前書き:

ここに画像の説明を入力してください

  1. apkモバイルでファイルを検討する場合、ファイルは、Activitys、Service sいます。
  2. これらのコンポーネントは定期的に互いに通信せず、独自のライフサイクルを持っていることを忘れないでください。これらは、それらが同時にアクティブであり、他の瞬間に非アクティブである可能性があることを示しています。

要件:

  1. 状況にApplication関係なく、変数全体とその状態全体にアクセスする必要があるシナリオが必要になる場合があります。Activityユーザーが使用しいるか
  2. 例として、ユーザーは、アクセスする必要がある人事情報(名前など)を保持する変数にアクセスする必要がある場合があります。 Application、。
  3. SQLiteを使用できますが、 Cursorし、何度も何度もそれを閉じると、パフォーマンスによくありません、
  4. Intentデータを渡すためにsを使用することもできますが、それは不格好であり、メモリの可用性によっては、特定のシナリオでアクティビティ自体が存在しない場合があります。

アプリケーションクラスの使用:

  1. 全体の変数へのアクセスApplication
  2. ApplicationアプリケーションクラスはActivitysまたは Servicessが実行される前に開始されるため、を使用して分析などの特定のことを開始できます。
  3. アプリケーション構成が変更されたときにトリガーされるonConfigurationChanged()と呼ばれるオーバーライドされたメソッドがあります(水平から垂直に、およびその逆)。
  4. また、Androidデバイスのメモリが不足するとトリガーされるonLowMemory()というイベントもあります。

要件の部分で、SharedPreferencesを使用してみませんか?

個人情報を保存する最初の例では、SharedPreferencesを使用できます。しかし、あなたが最後の部分で与えた例は私の疑問をクリアしました。ありがとう!
Saurabh Singh 2018

63

アプリケーションクラスは、アプリケーションの完全なライフサイクルを持つオブジェクトです。これは、アプリケーションとしての最上位層です。可能な使用例:

  • ApplicationクラスのonCreateをオーバーライドすることにより、アプリケーションの起動時に必要なものを追加できます。

  • アクティビティからアクティビティにジャンプするグローバル変数を保存します。Asynctaskのように。


4
アプリケーションをアプリケーショングローバル変数のダンプ場所として使用することは、大きなコードのにおいです。これを行うには、独自のカスタムでより具体的なクラスをシングルトンとして、または静的変数とともに使用する必要があります。
オースティン

5
@オースティンなぜ匂いなの?
RELM

1
ええ、なぜ匂い?前に述べたように、Applicationクラスは階層の最上位にあり、カスタムシングルトンクラスがその下にあるということで、昼食代を賭けることができます。したがって、プッシュが発生し、携帯電話のメモリが不足している場合、アプリケーションクラス(基本的にはアプリ全体)ではなく、カスタムシングルトンが最初に強制終了されます。
Starwave、2018

31

複数のアクティビティからアクセスする必要があるグローバル変数などのデータを保存したい場合があります。アプリケーション内のどこにでもある場合があります。この場合、Applicationオブジェクトが役立ちます。

たとえば、各httpの基本認証データを取得する場合リクエストは、アプリケーションオブジェクトに認証データのメソッドを実装できます。

この後、次のようなアクティビティでユーザー名とパスワードを取得できます。

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();

最後に、Applicationオブジェクトをシングルトンオブジェクトとして使用することを忘れないでください。

 public class MyApplication extends Application {
    private static MyApplication singleton;

    public MyApplication getInstance(){
        return singleton;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
    }
}

詳細については、アプリケーションクラスをクリックしてください。


2
これを親切に説明してください。それ自体がシングルトンであることがわかっている限り、Applicationクラスのシングルトンオブジェクトを明示的に作成する必要がある理由です。複数のアプリケーションオブジェクトを作成できますか?そして、その結果は何ですか?説明してください。
Syed Raza Mehdi 2016

いいえ、おそらく1つのアプリケーションクラスのみです。developer.android.com/guide/topics/manifest/...
IntelliJのAmiya

では、なぜそれのシングルトンオブジェクトを明示的に維持する必要があるのでしょうか。OSはそれを維持していませんか?実際、アクティビティクラスで作成されたアプリケーションオブジェクトがあり、マニフェストで言及されていないコードに遭遇しました。これは間違っていると思います。静的なシングルトンオブジェクトを作成している理由にも興味があります。あなたが考えるのは最良のアプローチです。返信いただきありがとうございます。
Syed Raza Mehdi


その中で*シングルトン*オブジェクトはどこにありますか
Dr. aNdRO

8

Applicationクラスは、任意のアクティビティから、またはContextオブジェクトがあればどこからでもアクセスできるシングルトンです。

また、ライフサイクルの少しを取得します。

アプリケーションのonCreateメソッドを使用して、分析ヘルパーのような、使用頻度の高い、頻繁に使用されるオブジェクトをインスタンス化できます。その後、どこからでもこれらのオブジェクトにアクセスして使用できます。


6
「あなたはまた、少しのライフサイクルを得ます。」あなたはそれを言い換えたいかもしれません。
wtsang02 2013

2
つまり、いくつかのライフサイクルコールを受け取りますが、アクティビティまたはフラグメントほどではありません。たとえば、ApplicationクラスにはonDestroy()はありません。
ジョンFハンコック

このクラスは自動的に作成されますか?
Konstantin Konopko 2015年

はい。AndroidManifest.xmlで正しく指定する限り。
ジョンFハンコック

いいえ、自動的には作成されません。作成してからマニフェストファイルで宣言する必要があります
Ojonugwa Jude Ochalifu

7

アプリケーションクラスの最適な使用法。例:起動完了時にアラームマネージャーを再起動する必要があるとします。

public class BaseJuiceApplication extends Application implements BootListener {

    public static BaseJuiceApplication instance = null;

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

    @Override
    public void onCreate() {
        super.onCreate();


    }

    @Override
    public void onBootCompleted(Context context, Intent intent) {
        new PushService().scheduleService(getInstance());
        //startToNotify(context);
    }

アプリケーションオブジェクトの静的参照を作成する必要がある理由を知りたいのですが、getApplication()を使用して取得し、アプリケーションクラスに型キャストすることができます。私が理解している限り、アプリケーションクラスはOS自体によって作成され、OSによって維持されるインスタンスは1つだけである必要があります。親切に説明してください、ありがとう。
Syed Raza Mehdi 2016

あなたは正しいです。アプリ内の任意のアプリケーションコンポーネントからgetApplicationを呼び出すと、アプリである単一のアプリケーション派生インスタンスが返されます。これは、Androidフレームワークによって内部的に処理されます。必要なのは、返されたインスタンスを、Applicationを拡張するカスタムクラスにキャストすることだけです。また、インスタンスをインスタンス化するために適切なクラスがAndroidフレームワークによって使用されるように、マニフェストを適宜設定する必要もあります。
Matt Welke 2017年

5

答えではなく観察同時に実行されている同じアクティビティの2つのインスタンスがある可能性があるため(1つは前景と見えないもの)

たとえば、ランチャーを介して通常どおりアクティビティを開始し、それを「最小化」します。アプリはandroid.intent.action.CREATE_SHORTCUTをサポートしているため、たとえばショートカットを作成するために、アクティビティの別のインスタンスを開始する別のアプリ(つまりTasker)を起動します。次にショートカットが作成され、このショートカットを作成するアクティビティの呼び出しによってアプリケーションオブジェクトのデータが変更された場合、バックグラウンドで実行されているアクティビティは、変更されたアプリケーションオブジェクトをフォアグラウンドに戻すと使用を開始します。


4

この質問には答えがないようです。私ApplicationはBill Pughのシングルトン実装(リファレンスを参照)を使用していて、一部のシングルトンにはコンテキストが必要なので、拡張します。Applicationこのようなクラスのルックス:

public class MyApplication extends Application {

    private static final String TAG = MyApplication.class.getSimpleName();

    private static MyApplication sInstance;

    @Contract(pure = true)
    @Nullable
    public static Context getAppContext() {
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() called");
        sInstance = this;
    }
}

そして、シングルトンは次のようになります。

public class DataManager {

    private static final String TAG = DataManager.class.getSimpleName();

    @Contract(pure = true)
    public static DataManager getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private DataManager() {
        doStuffRequiringContext(MyApplication.getAppContext());
    }

    private static final class InstanceHolder {
        @SuppressLint("StaticFieldLeak")
        private static final DataManager INSTANCE = new DataManager();
    }
}

このようにして、シングルトンを使用するたびにコンテキストを設定して、最小限のコードで遅延同期初期化を取得する必要はありません。

ヒント:Android Studioシングルトンテンプレートを更新すると、時間を大幅に節約できます。


3

Applicationクラスはさまざまな用途に使用できると思いますが、アクティビティやサービスを開始する前に、これらはすべて何かを行う必要性に関連付けられています。たとえば、私のアプリケーションではカスタムフォントを使用しています。呼び出す代わりに

Typeface.createFromAsset()

Assetsフォルダーからフォントの参照を取得するためにすべてのアクティビティから(そのメソッドを呼び出すたびに資産への参照を保持しているとメモリリークが発生するため、これは悪いことです)、これをonCreate()Applicationクラスのメソッドから実行します:

private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
    super.onCreate();

    appInstance = this;
    quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
                       "fonts/Quicksand-Regular.otf");
   ...
   }

今、私はこのように定義されたメソッドも持っています:

public static App getAppInstance() {
    return appInstance;
}

この:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

したがって、私のアプリケーションのどこからでも、私がしなければならないことは次のとおりです。

App.getAppInstance().getQuickSandRegular()

Applicationクラスのもう1つの用途は、デバイスがインターネットに接続されているかどうかを確認してから、実際に接続を必要とするアクティビティとサービスが開始され、必要なアクションが実行されることです。


1
よく言った。とても素敵な故障。
Oluwatobi Adenekan

3

ソース:https : //github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class

多くのアプリでは、アプリケーションクラスを直接操作する必要はありません。ただし、カスタムアプリケーションクラスのいくつかの許容される使用法があります。

  • 最初のアクティビティを作成する前に実行する必要がある特殊なタスク
  • すべてのコンポーネントで共有する必要があるグローバル初期化(クラッシュレポート、永続性)
  • 共有ネットワーククライアントオブジェクトなどの静的な不変データに簡単にアクセスするための静的メソッド

変更可能なインスタンスデータをApplicationオブジェクト内に格納しないでください。データがそこにとどまると想定した場合、アプリケーションはある時点で必然的にNullPointerExceptionでクラッシュします。アプリケーションオブジェクトは、メモリに永久に留まることが保証されているわけではなく、強制終了されます。一般的な考えに反して、アプリを最初から再起動することはありません。Androidは新しいApplicationオブジェクトを作成し、ユーザーが以前にいた場所でアクティビティを開始して、最初はアプリケーションが強制終了されなかったように見せかけます。


1

アプリケーションによって拡張されている場合、オブジェクトを作成せずに任意のクラスの変数にアクセスできます。それらはグローバルに呼び出すことができ、その状態はアプリケーションが強制終了されるまで維持されます。


1

拡張アプリケーションを使用すると、アプリケーションの実行期間全体を通して、必要なあらゆる種類の操作を確実に実行できます。これは任意の種類の変数になる可能性があり、サーバーからデータをフェッチする場合は、asynctaskをアプリケーションに配置して、毎回継続的にフェッチされるようにして、更新されたデータを自動的に取得できるようにします。このリンクを使用してください。詳細については...

http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android


それはスレッドではないので、「アプリケーションの実行期間全体を通じて必要なあらゆる種類の操作」。真実ではない。
Lassi Kinnunen

1

アクティビティを使用していない(アプリケーションはアクティビティではない)アプリケーションにバインドする必要がある長期実行スレッドまたはその他のオブジェクトについて、アプリケーションスコープに変数を格納する可能性があることを示す他の回答に追加します。バインドされたサービスを要求できないなど。アプリケーションインスタンスへのバインドが推奨されます。このアプローチの唯一の明らかな警告は、アプリケーションが生きている限りオブジェクトが生き続けるということです。そのため、メモリをより暗黙的に制御する必要があります。そうしないと、リークなどのメモリ関連の問題が発生します。

他に役立つと思われるのは、操作の順序で、アプリケーションがアクティビティの前に最初に起動することです。この時間枠では、必要に応じて、最初のアクティビティの前に発生する必要なハウスキーピングを準備できます。

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.