最初にはまった内容を、説明します。
問題点とかどうでもいいから、ログイン & ログアウト処理 の方法だけ教えてくれればいいんだよ!って方は, ログアウト処理の実装の方を参照してください
流れとして,
① MainActivity においてログイン済みかどうかの判定を行う (MainAvtivity は, レイアウトを持たないActivityで, アプリケーション起動時の処理などを行うものとする。)
② ログインがされていない場合は, LoginActivity に遷移し, その後ログインが完了したら HogeActivity に遷移
③ ログイン済みの場合は HogeActivity に直接遷移
④ HogeActivity においてログアウト処理が行われたら LoginActivity に遷移する。
ということを考える。
※ ちなみに, ログイン済みか否かは プリファレンスを利用して判断する。また, MainAvtivity はレイアウトを持たないので, android:nohistory 属性をtrueにして, バックキーで戻れないようにしておく。
この流れで作成したファイルは以下
< AndroidManifest.xml >
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.dev_grafr.app.logintest"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".MainActivity"
- android:label="@string/app_name"
- android:noHistory="true"
- android:launchMode="singleTask"
- >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name=".LoginActivity"
- android:label="@string/app_name"
- android:launchMode="singleTask"
- android:noHistory="true">
- </activity>
- <activity android:name=".HogeActivity"
- android:label="@string/app_name">
- </activity>
- </application>
- </manifest>
< MainActivity.java >
- package com.dev_grafr.app.logintest;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- public class MainActivity extends Activity {
- public static final String PREFERENCES_FILE_NAME = "preference";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if(loginCheck()){ // HogeActivity に遷移
- Intent intent = new Intent(getApplicationContext(), HogeActivity.class);
- startActivity(intent);
- }else{ // LoginActivity に遷移
- Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
- startActivity(intent);
- }
- }
- // ログイン判定
- public Boolean loginCheck(){
- SharedPreferences settings = getSharedPreferences(PREFERENCES_FILE_NAME, 0); // 0 -> MODE_PRIVATE
- if(settings == null) return false;
- int login = (int) settings.getLong("logged-in", 0);
- if(login == 1) return true;
- else return false;
- }
- }
< LoginActivity.java >
- package com.dev_grafr.app.logintest;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class LoginActivity extends Activity {
- public static final String PREFERENCES_FILE_NAME = "preference";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.login);
- ((Button) findViewById(R.id.loginBtn)).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- login();
- // ログイン後は HogeActivity に遷移
- Intent intent = new Intent(getApplicationContext(), HogeActivity.class);
- startActivity(intent);
- }
- });
- }
- // ログイン処理
- public void login(){
- SharedPreferences settings = getSharedPreferences(PREFERENCES_FILE_NAME, 0); // 0 -> MODE_PRIVATE
- SharedPreferences.Editor editor = settings.edit();
- editor.putLong("logged-in", 1);
- editor.commit();
- }
- }
< HogeActivity.java > ← 失敗例(正しいものは次回のブログで)
- package com.dev_grafr.app.logintest;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class HogeActivity extends Activity {
- public static final String PREFERENCES_FILE_NAME = "preference";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.hoge);
- ((Button) findViewById(R.id.logoutBtn)).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- logout();
- Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // ← FLAG_ACTIVITY_CLEAR_TOPを設定
- startActivity(intent);
- }
- });
- }
- // ログアウト処理
- public void logout(){
- SharedPreferences settings = getSharedPreferences(PREFERENCES_FILE_NAME, 0); // 0 -> MODE_PRIVATE
- SharedPreferences.Editor editor = settings.edit();
- editor.putLong("logged-in", 0);
- editor.commit();
- }
- }
[ 場合① ]
MainActivity -> LoginActivity -> HogeActivity と遷移した場合の Activityのスタックは, もちろん以下の通り
MainActivity は nohistory 属性が付いているので () をつけている
____________________________________
| ( MainActivity ) , LoginActivity , HogeActivity
____________________________________
そして, この時 HogeActivity において ログアウト処理を行い, LoginActivity に遷移する。その際にインテントに対して FLAG_ACTIVITY_CLEAR_TOP のフラグを付加することにより, HogeActivity が破棄されて遷移後のスタックは
____________________________________
| ( MainActivity ) , LoginActivity
____________________________________
となる。この場合は問題ない。
[ 場合② ]
しかし!!一度ログインを行い, ログイン済みの場合にアプリケーションを起動した際は, LoginActivity を介さないため,
____________________________________
| ( MainActivity ) , HogeActivity
____________________________________
というスタックになる。ここで ログアウト処理を行って LoginActivity に遷移した場合,
____________________________________
| ( MainActivity ) , HogeActivity , LoginActivity
____________________________________
となってしまうのである。つまり, ログアウトしたにも関わらず、LoginActivityにおいてバックキーを押すと, HogeActivityに戻ってしまう。
そこで, HogeActivity でログアウト処理 ----> MainActivity ----> ログイン判定 ----> LoginActivity という遷移で,
FLAG_ACTIVITY_CLEAR_TOPフラグを付加したインテントにより MainActivity を経由すれば, MainActivity 以外がスタックから廃棄され上手くいくのではないか?と考えたのだが, MainActivity にはnohistory属性がついており, これがあるとうまくいかないという現象に陥った。
つまり, nohistory属性 がついていると, スタックに積まれないないため, FLAG_ACTIVITY_CLEAR_TOPを利用してもActivityが破棄されないのではないかという結論に至る(間違ってたらすいません)
実際には, ログインごはログイン画面にはバックキーでは戻れないようにするため, LoginActivityにもnohistory属性をつけるので, そうすると場合①もできないんですよね。笑
だって, MainActivity と LoginActivity が nohistory でスタックが
____________________________________
| HogeActivity
____________________________________
となると考えられるわけですから。。。
つまり, この方法だと上手なログアウト処理ができませんでした。
ログアウトした場合, LoginActivity を除いた全ての Activity をスタックから排除するにはどうすればいいのか・・・。
ということで、次回はこの解決法を説明します。
0 コメント:
コメントを投稿