我正在使用Firebase创建应用程序,用户必须登录才能使用该应用程序。 MainActivity仅在用户使用FirebaseAuth
和FirebaseAuth.AuthStateListener
登录后启动。
因此,在主要活动中,我掌握了有关当前用户的所有信息。
我的问题是,在导航到其他活动时,最好是通过Intents将更多关于用户(或任何对象)的额外内容传递给SecondActivity
,还是最好从SecondActivity
中的Firebase数据库中读取{1}}?
(两者都适用于我的应用程序,但我正在思考良好的编程风格/结构以及对资源,速度和性能的思考)
另外值得一提的是,我要记住,几乎所有的活动都是'屏幕/ UI将通过有关当前对象的信息进行更新,因此我希望应用程序尽可能快速且响应迅速。对于我现在在项目中的一些代码,我必须使用Thread.sleep(x)
,让UI在更新UI之前等待数据库完成读取。这就是我目前在Google Maps Activity
中使用的内容。
用户的PK是用于登录的Gmail。每个用户都有几个ArrayLists(包含对象),这些ArrayLists在使用应用程序时会变大,因此最终会传递大量信息。
看一下下面的示例代码,但不要过多关注细节,它只是我现在放在那里的一些代码。重要的是如何在每个活动中检索和传递信息的一般结构:
MainActivity:
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("email", thisUser.getEmail());
startActivity(i);
SecondActivity:
private FirebaseDatabase Db;
private DatabaseReference destinationRef, userRef;
private String email;
private User thisUser;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.SecondActivity);
email = getIntent().getStringExtra("email");
Db = FirebaseDatabase.getInstance();
userRef = Db.getReference().child("Users");
destinationRef = Db.getReference().child("Destinations");
getInfoFromDb();
}
private void getInfoFromDb(){
userRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u;
for(DataSnapshot data : dataSnapshot.getChildren(){
u = data.getValue(User.class);
u.setUid(data.getKey());
if(email.equalsIgnoreCase(u.getEmail())){
thisUser = u;
/* Update something else, based on this info */
}
}
}
@Override
public void onCancelled(DataSnapshot dataSnapshot) { }
});
destinationRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Destination d;
for(DataSnapshot data : dataSnapshot.getChildren()){
d = data.getValue(Destination.class);
d.setUid(data.getKey());
if(thisUser.getCurrentTrip().getDestinationName().equalsIgnoreCase(d.getDestinationName())){
/*Something else, update UI or whatever */
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) { }
});
}
这是另一个(更短)的例子:
MainActivity:
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("email", thisUser.getEmail());
i.putExtra("rank", thisUser.getRank());
i.putExtra("points", thisUser.getPoints());
i.putExtra("someArray", thisUser.getSomeArray());
i.putStringArrayListExtra("somethingElse", thisUser.getSomeStringArrayList());
// And let's say we put in a lot more information
startActivity(i);
SecondActivity
thisEmail = getIntent().getStringExtra("email");
thisRank = getIntent().getStringExtra("rank");
thisEmail = getIntent().getIntExtra("points");
thisSomeArray = getIntent().getStringArrayExtra("someArray");
thisArrayList = getIntent().getStringArrayListExtra("somethingElse");
哪种方法更好?
1)第一个代码示例,我从SecondActivity
的数据库中读取信息。
2)从MainActivity
向SecondActivity
发送整个thisUser-object(可能会变得非常大,并且必须使用序列化)。
3)将MainActivity
与意图的更多(可能是很多)信息传递给其他活动。
同样,我正在考虑良好的编程结构,实践,风格,并关注速度,响应能力和资源。
答案 0 :(得分:0)
我会从数据库中检索数据,因为你说它可以提供更多信息。因此,最好只从SecondActivity
。
如果您使用intent
传递数据,则表示您在活动之间共享数据而不是存储数据。
另外,假设您要执行涉及多个节点的查询(可能是根目录下的两个nodes
(如join
)或嵌套的nodes
),您将不得不从数据库中检索数据以便能够执行该操作
答案 1 :(得分:0)
考虑测试。
在一种情况下,您需要测试框架传递所有这些额外数据以仅测试第二种方法。耦合增加了。该方法的内聚性较低,因为它不能独立操作。
在另一种情况下,测试框架不需要传入额外的数据,因为该方法本身会检索所需的信息。耦合减少。该方法更具凝聚力。
我的$ 0.02
答案 2 :(得分:0)
您的问题对于正在开发的应用程序非常具体。
通过意图传递数据或将数据保存在数据库中对于它是什么类型的数据以及由于某种原因丢失数据时的行动计划是非常主观的。
优点&缺点:在意图中传递数据
在意图中传递数据对于瞬态或推断数据是有益的,因为它是为采取某些操作而计算的,并且不应在每次加载活动时保留或检索。
与DB方法相比,代码将更加复杂,因为每次从一个活动遍历到另一个活动时,您必须添加代码以传递意图或检查传递的数据或在当前活动中添加新数据。如果系统崩溃,您将丢失所有数据和状态。
优点&缺点:DB方法
在数据库中拥有数据为您提供了一种在崩溃时恢复状态或将来作为检查点的方法。它还意味着你必须维护表和代码来处理它们,但它会很干净,因为接口将是干净的和定义的。同样,可以有多个保存和检索数据的调用。
您还需要考虑数据是否敏感。
简而言之,它完全取决于您的应用程序需求,您必须确定计算所需的数据以及需要保留的数据,并相应地使用混合方法以获得更高的可靠性和性能。