使用AccountManager的App流程

时间:2013-08-13 08:12:00

标签: android logic structure flow accountmanager

我的应用程序结构一直在苦苦挣扎。而且看起来这种结构在其他功能的开发中给我带来了很大的痛苦。所以在进一步讨论之前,我想提出一些建议,看看我在这里做错了什么。

我的应用程序的目的是连接到服务器,我使用AccountManager机制在设备上创建一个帐户并存储一个应该用于从服务器请求数据的令牌。在创建帐户时,一切都很好。 (它也适用于设备设置 - >添加帐户)

它是这样的:

MainActivity是一种活动,当您启动应用程序时,检查您是否拥有帐户。 如果您有一个帐户,我会在静态变量中获取令牌,以便MainActivity中的每个片段都可以访问它。 (假设工作但没有) 另外,我使用LoginActivity创建一个intent来在设备上创建一个帐户。 问题是我的片段无法获得此令牌,因为我正在使用AccountManager.getAuthToken()在线程中恢复令牌,因此在恢复此令牌之前会创建片段。因此我无法从我的服务器请求数据。

这让我觉得我的应用程序结构可能不那么好。 所以我在想,“如果我这样喜欢怎么办?” :

  • 用户启动应用
  • MainActivity就像一个引导程序,它检查帐户并获取令牌,如果设备上有帐户但不生成任何类型的视图,如当前版本。
  • MainActivity重定向到LoginActivity或ContentActivity(让我们这样调用它,一个应该使用我的令牌来填充ListViews中的数据的活动)

这样我就可以认为MainActivity会让令牌通过,但我不确定它在UX方面是否理想。 (在访问内容之前必须等待令牌)。 我现在对所有的建议持开放态度,因为我真的被卡住了。

谢谢!

更新1:

它更像是一个登录/注册应用程序逻辑,而不是处理AccountManager。我已经成功地使它们工作但我真的很挣扎于“最佳实践”应用程序逻辑结构,所以我不会因为它而遇到很多其他问题(因为我没有时间)。 我只需要一个图表或其他东西来向我展示一个“最佳实践”示例,以使我的应用程序按照我上面解释的方式工作。 我也遇到了一个问题,因为当我启动MainActivity时会检查一个帐户,如果没有,它会启动LoginActivity,但如果我按回去,我可以看到MainActivity(未填充)。

2 个答案:

答案 0 :(得分:5)

更多的一般做法是您正在使用的:

General Practice

此结构完全可以接受,并且是依赖于服务器的应用程序的正常流程。我更喜欢这样的模型,其中日志记录只是一些选项,其中一些内容不需要登录。每当触发需要登录的操作时,都会向用户显示登录信息。但是,您的模型应该可以正常工作。

我看到你的问题是

  1. I also ran into a problem because when I start the MainActivity it checks for an account and if not it launches LoginActivity but if I press back, i can see MainActivity (unfilled).

    可以使用不可见的Dispatch Activity解决此问题,该活动根据当前用户的状态启动MainActivity或LoginActivity。如图所示,您决定后只需finish()调度活动。您的LoginActivity负责重新启动DispatchActivity,它将在下一步重新定义。通常,不要覆盖LoginActivity的onBackPressed来启动Dispatch,只需在成功登录时启动Dispatch。

    但是,如果您决定在活动中显示某些内容,即使用户未登录,您也可以在登录请求后使用onActivityResult刷新MainActivity的内容。< / p>

  2. The problem is that my fragments can't get this token because, as i'm recovering the token in a thread using AccountManager.getAuthToken(), the fragments are created before this token is recovered.

    这个问题很正常。如果您在处理登录请求时已创建活动/片段,则必须能够通知这些活动/片段。基本上,如果您的片段没有显示&#34;未经验证的&#34;内容,那么你不应该面对这个问题,因为在你登录之前你甚至不应该创建这些片段。

    但是,如果您决定在活动/片段中显示某些内容,即使用户未登录,您也必须通知这些正在运行的组件有关状态更改的信息。一种方法是在您的活动中实现onResume,以检查用户是否已登录并执行适当的更改。另一种方法是使用本地广播来通知正在运行的活动/片段状态已更改:

    BroadcastReceiver mReciever = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
                //do whatever you want //check state
        }
    };
    
    public void onCreate(Bundle state) {
       //bla bla
       //bla bla
       LocalBroadcastManager.getInstance(mContext).registerReceiver(mReciever, new IntentFilter("your_package_name.LOGIN_STATE_CHANGED"));
    }
    

    每当状态发生变化时,发送广播:

    Intent intent = new Intent("your_package_name.LOGIN_STATE_CHANGED");
    LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    

  3. 当然,这可能会特定于案例。例如,如果您检查Touch App on Google Play,您会注意到我创建了一个可以看到的调度屏幕,无论用户的登录状态如何,然后要求用户登录,如果他进入需要登录的活动。在这种情况下,任何需要登录的活动都应相应地实现其onActivityResult,如果用户登录则更新ui,如果用户没有,则更新ui。另一方面,psst app on Google Play使用启动画面来决定是否根据用户的状态进入登录屏幕或主屏幕。

答案 1 :(得分:0)

示例代码..

public class DispatchActivity extends ActionBarActivity {


    SharedPreferences prefs = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        prefs = getSharedPreferences("me.sanath.megh", MODE_PRIVATE);
        boolean islogin = prefs.getBoolean("islogin",false);
        if(islogin)
        {
            Intent i = new Intent(this,homepageActivity.class);
            startActivity(i);
            finish();
        }else{

            Intent i = new Intent(this,LoginActivity.class);
            startActivityForResult(i,1);
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == 1) {
            boolean islogin = prefs.getBoolean("islogin",false);
            if(islogin)
            {
                Intent i = new Intent(this,homepageActivity.class);
                startActivity(i);
                finish();
            }else{

                Intent i = new Intent(this,LoginActivity.class);
                startActivityForResult(i,1);

            }
        }
    }
}