我正在尝试重构我的Android应用程序以获得更整洁和易懂的代码。我正在使用Firebase数据库来保持数据持久性。
我所做的,主要是将我的课程重构为单身,所以我可以轻松地在任何其他课程中使用它们。
这种方法适用于大多数类(Firebase存储控制器,GeoFire控制器,ecc),但我在Auth控制器上执行此操作时遇到了麻烦,因为它需要从Auth系统和Db中检索用户。
下面是我的代码的一些片段。
开始活动
public class StartActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
AuthController.getInstance(new ResultListener<AuthController>(){
@Override
public void onResult(AuthController result) {
AuthController authController = result;
Intent intent;
if ( authController.getUser() != null ) {
intent = new Intent(getApplicationContext(), MainActivity.class);
} else {
intent = new Intent(getApplicationContext(), LoginActivity.class);
}
startActivity(intent);
finish();
}
});
}
}
我的身份验证控制器
public class AuthController {
private static AuthController authController;
private User user;
public User getUser() {
return user;
}
public static AuthController getInstance(){
if( authController == null ){
getInstance(null);
//TODO return authController
}
return authController;
}
public static void getInstance(final ResultListener<AuthController> authControllerResultListener) {
initAuth(new ResultListener<AuthListener>() {
@Override
public void OnResult(AuthController authController) {
AuthController.authController = authController;
if(authControllerResultListener != null) {
authControllerResultListener.onResult(authController);
}
}
});
}
private static void initAuth(final ResultListener<AuthController> authListener) {
final AuthController authController = new AuthController();
FirebaseAuth mAuth = FirebaseAuth.getInstance();
mAuth.addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
final FirebaseUser authUser = firebaseAuth.getCurrentUser();
if (authUser != null) {
String authUserId = authUser.getUid();
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase.getReference("users").child(authUserId).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
authController.user = dataSnapshot.getValue(User.class);
authListener.onResult(authController);
}
@Override
public void onCancelled(DatabaseError databaseError) {
authController.user = null;
authListener.onResult(authController);
}
});
} else {
authController.user = null;
authListener.onResult(authController);
}
}
});
}
}
我的抽象活动,这是由我需要使用auth控制器实例的其他活动扩展的。
public abstract class MyAppActivity extends AppCompatActivity {
protected final AuthController authController = AuthController.getInstance();
}
结果侦听器界面
public interface ResultListener<ResultType> {
void onResult(ResultType result);
}
所以我想做的是获取一个以同步方式包含用户的auth控制器实例,但当然,必须从firebase中检索用户,所以看起来好像难以保持同步。
有些尝试
我尝试使用新的Thread和join()暂停主线程直到子线程完成,但看起来Firebase侦听器在主线程上运行,因此代码在执行期间卡住了。与AsyncTask相同(见下文)。
新主题
public static AuthController getInstance(){
if( authController == null ){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
initAuth(new ResultListener<AuthController>() {
@Override
public void onResult(AuthController authController) {
AuthController.authController = authController;
}
});
}
});
thread.run();
thread.join();
}
return authController;
}
的AsyncTask
public static AuthController getInstance(){
if( authController == null ){
final Semaphore semaphore = new Semaphore(0);
InitAuthAsync initAuthAsync = new AuthController().new InitAuthAsync();
initAuthAsync.setResultListener(new ResultListener<Void>() {
@Override
public void onResult(Void result) {
semaphore.release();
}
});
initAuthAsync.execute();
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return authController;
}
private class InitAuthAsync extends AsyncTask<Void, Void, Void>{
private ResultListener<Void> resultListener;
public void setResultListener(ResultListener<Void> resultListener) {
this.resultListener = resultListener;
}
@Override
protected Void doInBackground(Void... voids) {
initAuth(new ResultListener<AuthController>() {
@Override
public void onResult(AuthController authController) {
AuthController.authController = authController;
resultListener.onResult(aVoid);
}
});
return null;
}
}
有什么建议吗?
答案 0 :(得分:0)
你的代码很乱。简单的观察者模式将适用于您的情况。我建议你使用轻量级且易于使用的Eventbus Library。
答案 1 :(得分:0)
如果有人需要,我发现了一个解决方案。请注意,这不是与firebase一起使用的最佳架构。
time