2

おそらく私のアクティビティのonCreate()で、アプリが以前に通常のホーム/戻るボタンに従って閉じられたかどうか、またはユーザーが実際にAndroid設定に入り、強制終了を選択したかどうかを知りたいです。

これらの2つのケースを区別することは可能ですか?

編集:

私が何を意味するのか十分に説明できなかったのではないかと思います。アクティビティのライフサイクルドキュメントを読みましたが、それはかなりよく理解しています。

基本的には、アクティビティがいつ作成されたか、ユーザーが以前にAndroid設定に移動して、強制停止を押したかどうかを知りたいだけです。アプリが強制的に停止された場合は、アクションを実行します(具体的には、起動時にスプラッシュ画面を表示します)。

以下の回答の多くは、onStop()またはonDestroy()にフラグを設定でき、ユーザーが強制停止を押してもこれらのメソッドは呼び出されないことを示しています。問題は、次のシーケンスのために、これらのメソッドがそのポイントに到達する前にすでに呼び出されていることです。

  1. アプリはアクティブ状態であり、使用されています
  2. ユーザーが戻るボタン(onStop()、onDestroy()が呼び出される)、ホームボタン(onStop()が呼び出される)、または最近のアプリボタン(onStop()が呼び出される)を押す
  3. ユーザーがAndroid設定に入り、強制停止をタップします

その状況では、onStop()の共有設定にフラグを設定しますが、ユーザーが強制停止を押すと、フラグはonCreate()で引き続きアクティブになります。

ユーザーが設定で強制停止を押さない限り、スプラッシュ画面を表示したくありません。私はこれが行われるべき方法ではないことを知っています...しかし、この決定は私によってなされませんでした。

4

8 に答える 8

1

より簡単な方法があるかどうかはわかりませんが、アクティビティのonStop関数のフラグで更新されるSharedPreferencesオブジェクトを作成できます。そして、onCreateでフラグを確認します。ユーザーがアプリを強制終了した場合にonStopまたはonDestroyが呼び出されるとは思いません。

于 2012-02-22T18:19:07.807 に答える
1

私は昨日同じ問題に遭遇しました、そしてこれは私がマーク・マーフィーによって述べられたものであると私が見つけたものです。しかし、私はなんとかそれをクラックすることができました。

実際、「強制停止」を押すと、システムは2つを除いてアプリケーションが占有しているすべてのメモリをクリアします。

1:the shared preferenceおよび2:sqlite database

ブール変数をアプリケーションに格納し、値を操作して、アプリケーションを起動するたびにチェックすることで、このトリックを実行しました。これで完了です。

CONSTANTS.java

package com.mehuljoisar.forcestopdemo;

public class CONSTANTS {

//the changes made to value of below variable will be cleared on force stop,so whenever force stop occurs,the value of variable will be "isForceStopped=true" again.
    public static boolean isForceStopped = true;
}

MainActivity.java

package com.mehuljoisar.forcestopdemo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

    private Context mContext;
    private Intent i;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initialize();


        if(CONSTANTS.isForceStopped)
        {
        //this block of code will be executed in 2 scenario,
        //1: when application is started for very first time
        //2: when application is started after force stopping
            Toast.makeText(mContext, "Display Splash-screen and move to next screen", Toast.LENGTH_SHORT).show();
        //don't forget this part,it's important to make change so that next time splash screen can be avoided
             CONSTANTS.isForceStopped=false;

        //and then launch next screen
            launchSecondScreen();
        }
        else
        {
        //directly launch next screen
            launchSecondScreen();
        }
    }

    private void launchSecondScreen() {
        i.setClass(mContext, SecondActivity.class);
        startActivity(i);
        finish();
    }

    private void initialize() {
        mContext = this;
        i = new Intent();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

SecondActivity.java

package com.mehuljoisar.forcestopdemo;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

}

AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mehuljoisar.forcestopdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.mehuljoisar.forcestopdemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.mehuljoisar.forcestopdemo.SecondActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

お役に立てば幸いです!!

于 2013-02-20T10:40:23.137 に答える
0

アクティビティではなく、サービスからステータスフラグを書き込むのはどうですか?アクティビティのライフサイクルは引き続き完了しますが、サービスのライフサイクルは完了しないはずです。

要件と同じではありませんが、十分に近い可能性があります。この要件がないアクティビティを表示している場合は、サービスを停止して(後で再起動して)ください。または、サービスに何らかのイベントストリームを書き込んでもらい、それを使用して起動時に何を表示するかを判断します。

于 2012-03-17T05:25:17.127 に答える
0

まず、再開と作成を混同しているようです。アプリの基本事項、特にアクティビティライフサイクルに関する内容を必ず読んでください。その状態図は役に立ちます。

ユーザーがアプリケーションから「バックアウト」しても、必ずしも破棄されるとは限りません。onPause()実際、開発者がアクティビティを明示的に破棄するフックをいくつか入れない限り、おそらく破棄されません。

理解すべきAndroidアプリのライフサイクルで最も重要な概念は次のとおりです。

Android OSは、アプリケーションが存続する期間についてはまったく保証しません。ただし、必要かどうかに関係なく、いつでもアプリケーションが停止する可能性があるという保証があります。

常にそれに応じてアプリを作成する必要があります。ライフサイクルの起動フックと終了フックをすべて入力することをお勧めします。ユーザーがアプリからハードウェアボタンを元に戻すと、アプリは必ずしも破棄されませんが、アプリを強制終了して閉じると、完全に破棄されます。アプリがどのように閉じられたかを理解しようとする代わりに、これを処理する「適切な」方法は、アクティビティの状態に基づいて適切な量のクリーンアップを実行するように、、、およびメソッドを設定することonPause()ですonStop()onDestroy()、そして多分ある種のPreferenceオブジェクトまたは状態変数を持っていて、それは次の場合にのみ反転しますonDestroy()技術的には、ユーザーがタスクマネージャーを介してアプリを「強制終了」しなくても、OSはアプリを「強制終了」できるため、と呼ばれます。

于 2012-02-22T18:20:41.143 に答える
0

ユーザーが「forceclose」でアプリケーションを閉じた場合、「onStop」メソッドは実行されません。そのメソッドにフラグ(ファイルへの保存、ユーザー設定、SQLなど)を入れることができます。次回アプリケーションを起動するときは、そのフラグを確認してください。

于 2012-02-22T18:15:45.000 に答える
0

ホームアクティビティのを上書きonBackButtonPressedします(通常、戻るボタンを使用すると、アプリケーションのメインアクティビティが閉じます)。

この関数で変数(たとえば、lastforceCloseをfalseとして)SharedPreferencesを設定してから、onbackbuttonpressed()またはfinish()のスーパーメソッドを呼び出してアクティビティを終了します。

次回アクティビティを開始するときはいつでも、sharedpreferencesで変数をチェックアウトして、lastforceClose変数がfalseに設定されているかどうかを確認できます(そして、自分でtrueに変更します)...

また、ユーザーがAndroid設定を使用している場合は、ここでケースを処理することもできdeleted dataます(つまり、共有設定のxmlファイルにキーが存在しないなど)。

于 2012-02-22T18:17:58.647 に答える
0

100%確信はありませんが、これでうまくいくはずです。
1)一部の永続ストレージのアクティビティのonDestroyに状態(通常のシャットダウン)を保存します。(SharedPreferencesまたはSQLite)
2)onCreateで状態を確認します。正常なシャットダウンの場合はアプリが正常に閉じられ、そうでない場合は強制的に閉じられます。状態をリセットします。

于 2012-02-22T18:18:45.607 に答える
0

すべてのアプリライフサイクルイベントの記録を保持してからonCreate()s、最後に記録されたイベントが正常であったかどうかをさまざまにチェックインしてみてください。そうでない場合は、何かが起こったと合理的に推測できます。ユーザーが強制的に閉じると、システムkill(2)がアプリにを送信するだけだと思います。その場合、表示は表示されません。これは役立つかもしれません。

また、自分が求めていることを別の方法で達成できるかどうかを検討することもできます。アプリが完全にステートレスである場合は、いかなる種類のシャットダウンでも問題はありません。アプリに状態がある場合、理論的にはすべてのデータ/アプリトランザクションがACIDを達成できるため、クラッシュや強制終了による不整合を回避できます。

それは助けになりますか、それとも何か他のものを求めていますか?

于 2012-02-22T18:37:45.640 に答える