java - Android:登出系统和android生命周期

标签 java android login android-lifecycle

在周末,我开始构建我的第一个Android应用程序。由于需要向我的应用程序的用户询问用户凭证(这些凭证用于进一步的Web服务使用),因此我想模拟一个“登录系统”。在我的应用程序启动时,应告知用户输入其凭据。当用户长时间不活动时,我想关闭输入的凭据并“注销”该用户。
在进行编码时以及在进行测试时,我意识到我认为自己可以采用的方式行不通。在一次又一次地阅读了文档和一些SO问题之后,如果我已经完全了解应用程序/活动的生命周期及其可能性,我就会越来越多地问自己。因此,我想寻求帮助以了解生命周期及其对我的应用程序的影响。所以是的,这可能是几个问题:/

目前,我的应用包含以下活动:


搜索活动(一旦启动应用程序即会打开)
激活设置(可以从搜索对话框中访问并具有指向搜索对话框的链接)


用户在搜索对话框中输入ID后,我想打开一个与搜索结果(NYI)有关的活动。

当开始实施用户身份验证时,我的想法如下:
每次调用一个活动的onResume()时,我需要检查a)用户凭证是否已经存储,b)用户的最后一个动作是否少于X分钟。如果这些失败,我想显示一个“登录面板”,用户可以在其中输入其凭据,然后将其存储在SharedPreferences中。为此,我执行了以下操作:

我首先建立一个父活动,其中包含检查和对SharedPreferences的引用

public class AppFragmentActivity extends FragmentActivity  {

  protected SharedPreferences sharedPref;
  protected SharedPreferences.Editor editor;    

  protected String WebServiceUsername;
  protected String WebServicePassword;


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

  } 


  @Override
  protected void onResume () {
    super.onResume();


    // Check if user is "logged in".
    // Meaning: Are there given user credentials and are they valid of was the user inactive for too long?

    // We only do this "onResume" because this callback is the only one, which is called everytime an user 
    // starts/restarts/resumes an application
    checkForUserCredentials();


    // Set new "last action" now "now"
    setLastAction(new Date().getTime());
  }

  @Override
  protected void onStart () {
    // Fill content
    super.onStart();

    // Set global sharedPreferences
    sharedPref = this.getSharedPreferences(getString(R.string.FILE_settings_file), Context.MODE_PRIVATE);

  }



  /*
   * Checks if user credentials are valid meaning if they are set and not too old
   */
  private void checkForUserCredentials() {  

    long TimeLastAction = sharedPref.getLong(getString(R.string.SETTINGS_USER_LAST_ACTION), 0);
    long TimeNow = new Date().getTime();

    // Ask for User credentials when last action is too long ago
    if(TimeLastAction < (TimeNow - 1800)) {
      // Inactive for too long
      // Set back credentials 
      setUsernameAndPassword("", "");

    }
    else
    {
      WebServiceUsername = sharedPref.getString(getString(R.string.SETTINGS_USER_USERNAME), "");
      WebServicePassword = sharedPref.getString(getString(R.string.SETTINGS_USER_PASSWORD), "");                
    }

  }

  /*
   * Saves the given last action in the sharedPreferences
   * @param long LastAction - Time of the last action
   */
  private void setLastAction(long LastAction) {
    editor = sharedPref.edit();
    editor.putLong(getString(R.string.SETTINGS_USER_LAST_ACTION), LastAction);
    editor.commit();        
  }

  /*
   * Saves the given username and userpassword sharedPreferences
   * @param String username
   * @param String password
   */
  private void setUsernameAndPassword(String username, String password) {
    editor = sharedPref.edit();
    editor.putString(getString(R.string.SETTINGS_USER_USERNAME), username);
    editor.putString(getString(R.string.SETTINGS_USER_PASSWORD), password);
    editor.commit();    

    WebServiceUsername = username;
    WebServicePassword = password;
  }

  /*
   * Method called when pressing the OK-Button
   */
    public void ClickBtnOK(View view) {
        // Save User-Creentials

      EditText dfsUsername = (EditText) findViewById(R.id.dfsUsername);
      String lvsUsername = dfsUsername.getText().toString();        

      EditText dfsPassword = (EditText) findViewById(R.id.dfsPassword);
      String lvsPassword = dfsPassword.getText().toString();        

      if(lvsUsername.equals("") || lvsPassword.equals("")) {
        TextView txtError = (TextView) findViewById(R.id.txtError);
        txtError.setText(getString(R.string.ERR_Name_or_Password_empty));
      }
      else
      {
        // Save credentials
        setUsernameAndPassword(lvsUsername, lvsPassword);
        setLastAction(new Date().getTime());

        // open Searchactivity
          Intent intent = new Intent(this, SearchActivity.class);
          startActivity(intent);            

      }         

}   


“登录掩码”为setContentView(R.layout.activity_appfragmentactivity);

然后,我创建的其他两个活动将扩展此父类。这是其中之一:

public class SearchActivity extends AppFragmentActivity {
  SearchFragment searchfragment;

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

  @Override
  protected void onResume() {
    super.onResume();

    if(WebServiceUsername.equals("") && WebServicePassword.equals("")) {
      // Username not set. Re"login".
      Intent intent = new Intent(this, AppFragmentActivity.class);
      startActivity(intent);            
    }
  }

  @Override
  protected void onStart() {
    super.onStart();
  }

  // ...
}  


据我现在所了解的生命周期,它应该按以下方式工作:当我的应用程序启动(SearchActivity设置为LAUNCH)时,该应用程序应进入父类的onResume()。在那里看到凭据尚未存储,并打开AppFragmentActivity的布局,即登录名。输入后,用户将被重定向到SearchActivity,它现在显示“确定的凭据在那里,让我们继续前进”。但这不会发生,因为未显示登录名。所以我认为我的onResume()可能是错误的。也许我的主意不好?到目前为止,我以为我也了解生命周期,但是显然我不明白吗?

然后,我对类似问题进行了四处浏览。我在这里看到的一件事是给一个用户的注释,该用户想要建立一个与我的类似的“注销”机制,他必须在每个活动中都实施此机制。我考虑了一下,问自己:“为什么我的每项活动都来自同一个父母,所以我必须在每项活动中都覆盖onResume()?当孩子中没有onResume()时,父母中的一个应该是称为”。建议SO问题中的用户将服务用作后台线程,以在其中倒数计时器进行注销。然后,我在文档中阅读了服务文章,然后完全迷失了方向:

服务有两种类型:启动服务和有界服务。一个启动的服务由一个活动启动,然后在后台运行,直到不停止时地狱冻结。因此,它完全独立于任何应用程序,但是程序员必须/不再需要它时,应停止它。有界服务绑定到一个或多个应用程序组件,并在所有有界组件结束时停止。我认为这对我来说可能是一个不错的选择,但是当我进一步思考时,我问自己:如果我的一个启动了它(例如登录对话框),然后关闭了该服务,而其他活动总是在那里启动不可能的感觉。因此,此服务必须不限于任何组件,而应限于我的应用程序。但是,Android应用程序的生命周期如何?如何在我的应用程序中保持信息“全局”。我知道我可以使用“意图”在活动之间切换数据。

这种越来越多的“雾云”使我问自己:“我应该只使用一个活动,并尝试使用片段来切换所有输入/输出吗?”

所以我的问题是(我想所有的问题,但是我不确定)。


我写父类的想法对所有扩展子代都进行检查是好是坏,并​​且按我的理解可以正常工作吗?
我是否必须重写子项中的每个onResume()以便仅调用父项进行检查?
您能给我一个提示,为什么我的“登录系统”不起作用吗?
什么是Android应用程序的生命周期,我如何与之交互?
我应该只使用一个活动,并使用片段来切入/切出所有内容,还是进行多个活动,其中一些活动使用片段(重用经常使用的部件)是一种好方法?


感谢您的建议

最佳答案

最后我要做的是:

我从父类中删除了“登录”内容,成为一个独立的活动。当凭据与调用方的finish()一起无效时,将调用此活动。因此,我不会建立循环并丢弃未使用的活动。

关于java - Android:登出系统和android生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18189009/

相关文章:

login - “Evaluate Now, Respond Later”的最佳实践?

java - 与 AWS CLI 和 Java SDK 不同的 SQS 队列 URL

java - 使用 ActivityLifecycleCallbacks 自动记录 Android 生命周期事件?

php - 检查 PHP session - ISSET($SESSION - 不工作

authentication - 使用电子邮件而不是用户名的Symfony2身份验证/登录

Android:将图像附加到电子邮件 Intent - 错误

java - 2 路 ssl tomcat 无状态服务规模

java - 无法理解如何调用非静态方法

java - 使用架构自动检测写入 BigQuery 的数据流作业

android - 在 PreferenceFragmentCompat 中为 PreferenceCategory 设置标题样式