0

私は同じオブジェクトを使用する2つの方法を持っています。私の条件を実行するためにオブジェクトがnullでないのを待ってください。

Object A; 

public void methodA() { 
    //Client code talks to server, create data, and instantiate A. 
    A = new A(); 
} 

public void methodB() { 
    if(A!=null) { 
     //do something 
    } 
} 

これは私が達成しようとしているが、私は方法Aにオブジェクトをインスタンス化していた瞬間に、私のアプリは、サーバーに話していると、そのオブジェクトのためのデータを作成するものに単純化されたロジックです私のアプリが実行されているときメソッドB()ObjectAがnullです。

私のアプリケーションをデバッグするときに、ObjectAにインスタンスがあり、デバッグが遅いプロセスであるため、methodB()が正しく実行されますが、実行時にObjectAがヌル。私は、通知と待機を使用しようとしましたが、私は私のアプリがクラッシュするようにnullを返すので、同期ブロックで私のobjectAを設定することができません。


EDIT:私の現在のコードの追加:サーバがfirebaseUserインスタンスを作成する前methodBが実行されているので

//Firebase Authentication 
private FirebaseAuth mAuth; 
//Database reference 
private DatabaseReference databaseReference; 

public void methodA() { 
    mAuth.createUserWithEmailAndPassword(
      getUserEmailAddress(), getUserPassword()) 
      .addOnCompleteListener(ActivityA.this, new OnCompleteListener<AuthResult>() { 
       @Override 
       public void onComplete(@NonNull Task<AuthResult> task) { 
        Log.d(TAG, "createUserWithEmailAndPassword: onComplete" + task.isSuccessful()); 
        if (!task.isSuccessful()) { 
         Toast.makeText(ActivityA.this, "authentication failed", 
           Toast.LENGTH_LONG).show(); 
        } 
       } 
      }); 
} 

public void methodB() { 
    if (mAuth.getCurrentUser() != null) { 
     databaseReference.child(mAuth.getCurrentUser().getUid()).setValue(userInformation); 
    } 
} 

mAuth.getCurrentUser()はnullを返すされています。より高いレベルの技術が同様にありますがあなたは、wait()/notify()でこれを行うことができ

+0

ここでは、methodAがAをインスタンス化するか、サーバーが応答するときにA非同期メソッドでインスタンス化されるかは実際に表示されていますか? –

+0

@ JemarJonesので、サーバーがuserIdを作成し、それが私のオブジェクトです。私は 'A = new A();'を入れて説明しましたが、実際にはサーバ側で起こっています。 –

+0

私はあなたがここで最高の解決方法を決定するのに役立つもっと詳細なものを見る必要があると思うと思います –

答えて

2

あなたの実際の状況を見た後、私は他の回答に示す待機/通知方法は、あなたのケースのために最善の解決策ではないと信じています。

ここでの基本的な問題は、ユーザーが一度サインイン/認証されると動作する必要があることです。これは、非同期の方法で取得したオブジェクトで同期アクションを実行しようとする典型的なケースです。これらの状況の一般的なベストプラクティスは、コールバックを使用して非同期アクションの結果を取得した後にのみアクションを実行することです。ここでの大きな解決策は、Firebaseが認証状態の変更に提供するコールバックを使用することです。ドキュメントから:

mAuthListener = new FirebaseAuth.AuthStateListener() { 
    @Override 
    public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
     FirebaseUser user = firebaseAuth.getCurrentUser(); 
     if (user != null) { 
      // User is signed in 
      Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 
     } else { 
      // User is signed out 
      Log.d(TAG, "onAuthStateChanged:signed_out"); 
     } 
     // ... 
    } 
}; 

ここから、メソッドBを呼び出すためのロジックを特定できます(特定のユースケースによります)。

+0

@EJP私のアクティビティのonCreateメソッドにすでに 'mAuthListener'リスナーがあります。私のフランクへの返事を見てください。 –

+0

@RedaMこれは私の答えです。私はあなたがあなたが説明している問題をどのように経験しているのか理解していません。どの認証コードを実行する前にauthコールバックの1つを待っている場合(methodB仮定)、nullオブジェクトに関する問題は発生していないはずです。 –

+1

私はあなたの提案から間違った場所で間違ったオブジェクトを使用したことに気付きましたが、あなたの作品は絶対にうまく動作します!どうもありがとう ! –

0

public synchronised void methodA() 
{ 
    // ... 
    a = new A(); 
    notifyAll(); 
} 

public synchronised void methodB() 
{ 
    while (a == null) 
    { 
     wait(); 
    } 
    // do something 
} 

は通知&を待つ使用しようとしてについてのあなたの文を理解することはできません。私はこれが働かない理由は見当たらない

+0

返信ありがとうございます。より高いレベルのテクニックのベストプラクティスですか、私のシナリオまで待って通知することをお勧めしますか? –

+0

何でも好きです。これは動作します。本当に「ベストプラクティス」のようなものはなく、あなたの問題に適したものだけです。 – EJP

0

は:

Object A; 

public synchronized void methodA() { 
    //Client code talks to server, create data, and instantiate A. 
    A = new A(); 
    this.notify(); 
}; 

public synchronized void methodB() { 

    while (A==null) { 
     this.wait(); 
    } 

    // do something 
} 
2

多くの場合、非同期コードの場合、問題は「最初にAを取得し、次にBを実行して」から「Aを開始し、次にAが完了するとBに」という問題を解決することです。

public void createUserAndSaveToDatabase() { 
    mAuth.createUserWithEmailAndPassword(getUserEmailAddress(), getUserPassword()) 
     .addOnCompleteListener(ActivityA.this, new OnCompleteListener<AuthResult>() { 
      @Override 
      public void onComplete(@NonNull Task<AuthResult> task) { 
       if (task.isSuccessful()) { 
        FirebaseUser user = task.getResult().getUser(); 
        databaseReference 
         .child(user.getUid()) 
         .setValue(...); 
       } 
      } 
     }); 
} 
+0

私はまだ同じ問題を抱えています。初めてアプリケーションを実行するときはいつも、firebaseコンソールで認証が作成されていますが、アプリケーションを2度実行するまではリアルタイムデータベースのトークンは表示されません。オブジェクトがnullでなくなるまでスレッドをブロックすることを考えました。したがって、私の最初の質問(待​​機して通知する)。 –

関連する問題