Java Android:注销系统和Android生命周期

Java Android:注销系统和Android生命周期,java,android,login,android-lifecycle,Java,Android,Login,Android Lifecycle,周末,我开始构建我的第一个android应用程序。因为我需要向我的应用程序的用户询问用户凭据[用于进一步使用Web服务],所以我想模拟一个登录系统。在我的应用程序启动时,应告知用户输入其凭据。当用户长时间处于非活动状态时,我希望取消输入的凭据并注销该用户。 在编码和测试过程中,我意识到我所认为的方法行不通。在一次又一次地阅读docu和几个SO问题之后,如果我已经完全理解了应用程序/活动的生命周期及其可能性,我会越来越多地问自己。因此,我想寻求帮助,了解生命周期及其对我的应用程序的相关影响。是的,

周末,我开始构建我的第一个android应用程序。因为我需要向我的应用程序的用户询问用户凭据[用于进一步使用Web服务],所以我想模拟一个登录系统。在我的应用程序启动时,应告知用户输入其凭据。当用户长时间处于非活动状态时,我希望取消输入的凭据并注销该用户。 在编码和测试过程中,我意识到我所认为的方法行不通。在一次又一次地阅读docu和几个SO问题之后,如果我已经完全理解了应用程序/活动的生命周期及其可能性,我会越来越多地问自己。因此,我想寻求帮助,了解生命周期及其对我的应用程序的相关影响。是的,这可能是一个问题:/

目前,我的应用程序包括以下活动:

启动应用程序后打开的搜索活动 设置活动,可从“搜索”对话框访问,并有一个指向“搜索”对话框的链接 用户在搜索对话框中输入ID后,我想打开一个与搜索结果NYI相关的活动

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

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

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);            

      }         

}   
就我现在对生命周期的理解而言,这应该如下所示:当我的应用程序启动时,SearchActivity设置为启动,应用程序应该进入父类的onResume。在那里,它看到凭据尚未存储,并打开AppFragmentActivity的布局,即登录。输入后,用户将被重定向到SearchActivity,现在可以看到ok凭证在那里,让我们继续前进。但这不会发生,因为没有显示登录名。所以我认为我的简历可能是错的。也许我的想法不好?到目前为止,我还以为我也了解生命周期,但显然我不明白

然后我环顾四周,寻找类似的问题。我在这里看到的一件事是一个用户的评论,他想建立一个类似于我的注销机制,他必须在每个活动中实现这一点。我想了想,问自己为什么我必须在我的每一个活动中覆盖onResume,而它们都来自同一个家长?当子级中没有onResume时,应调用父级中的一个。SO问题中的用户被建议使用服务作为后台线程,以便为注销倒计时。然后我读了文档中的服务文章,然后完全迷失了方向:

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

越来越多的雾云让我问自己:我是否应该只使用一个活动,并尝试使用片段切换所有内容

所以我的问题是,我想这就是全部,但我不再确定:

我写一个检查所有扩展子类的父类的想法是正确的还是错误的,它是否按照我的理解工作? 我是否需要覆盖child中的每个onResume来调用父项进行检查? 你能告诉我为什么我的登录系统不工作吗? android应用程序的生命周期是什么?我如何与之交互? 我应该只使用一个活动并使用片段切换所有内容,还是有几个活动并且其中一些活动使用片段来重用常用的部分是一种好方法?
感谢您的建议

我最后做了以下几点:

我将登录从父类中删除为独立活动。当凭据无效并完成调用时,将调用此活动。所以我不会构建循环并删除未使用的活动

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();
  }

  // ...
}