2016-03-27 14 views
0

私はここに1つの変なコードを持っています。私も名前を付けることはできません。それは自分で誤解されてしまいます。奇妙なコードの変数へのアクセス

String [] x = new String[1]; 

someWorkableMethod(new CoolClass() 
{ 
    @Override 
    public void Something(String s) { 
    x[0] = s; 
} 
}); 

p.s.とにかく構文エラーはありません。 実際に変数sはnullではありませんが(Log.dは正常な結果を返します)、Log.d(x [0])にしようとするとExceptionを返しますそのx [0]はnullです。 Something()のx [0]にsの値を書き込む方法は?ご協力ありがとうございます! )

必要に応じてフルコード。新しく宣言CoolClass

public class Connection { 

private String key = "SMTH"; 
private static final String BASE_URL = "SMTH"; 
AsyncHttpClient client = new AsyncHttpClient(); 

private String post(String url, RequestParams params, AsyncHttpResponseHandler Handler) { 
client.post(url, params, Handler); 
//client. 
return ""; 
} 

public String createAuth(String login, String password, String device) { 
RequestParams params = new RequestParams(); 
params.put("login", login); 
params.put("password", password); 
params.put("device", device); 
params.put("key", this.key); 
params.put("method", "createAuth"); 
final String[] res = new String[1]; 
post(BASE_URL, params, new TextHttpResponseHandler(){ 

@Override 
public void onFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { 
super.onFailure(statusCode, headers, responseBytes, throwable); 
} 

@Override 
public void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) { 
super.onSuccess(statusCode, headers, responseBytes); 
} 

@Override 
public void onFailure(int i, Header[] headers, String s, Throwable throwable) { 

} 

@Override 
public void onSuccess(int i, Header[] headers, String s) { 
Log.d("LoginActivity", s); 
res[0] = s.toString(); 
} 
}); 
// Log.d("LoginActivity", res[0]); 
return res[0]; 
} 
} 
+0

つまり、Something()のx変数にアクセスできません。私はアクセスする必要があります。たとえば、クラスでは、これで何かを得ることができます。私はそれに似た解決策を探しています。 – MrGeorgeous

+0

'someWorkableMethod()'の本文を投稿できますか? –

+0

Sasha、編集したバージョンの質問をご覧ください。サポートしてくれてありがとうございます – MrGeorgeous

答えて

2

これは、匿名の内部クラスから変数にアクセスしたり変更したりするための回避策です。あなたは

String [] x = new String[1]; 

final String [] x = new String[1]; 

変更することができ、これはそれにアクセスできるようにする必要があります。私は個人的にこのメソッドが気に入らないので、匿名関数の中から値を設定する方が良い方法があります。また

、匿名内部クラスを使用しているとき、彼らはもはや自分のアクティビティのライフサイクルよりも続く場合、それは活動を引き起こす可能性があります、慎重にあなたが/ログ値を返している

EDIT

// Log.d("LoginActivity", res[0]); 
return res[0]; 

を漏らしますres[0]が割り当てられます。 success()は、http要求まで呼ばれていない完了したが、それとこのres[0]がnull

+0

ありがとうございますが、私はすでにfinal String [] x = new String [1]を追加しています。それは質問にそれを適用することを忘れた私のせいです。ファイナルはすでに使用されています。 – MrGeorgeous

+0

@MrGeorgeous私の編集を参照 – Sourabh

+0

ありがとうございます、あなたは完全に正しいです!このような間違いをどのようにして避けることができますか? ) – MrGeorgeous

0

x[0]は、同じスコープ内ではありません。 CoolClass宣言がそれ自身のファイルであると想像すれば、これは概念化するのが簡単かもしれません。

x文字列配列も渡すと、このようなことが起こります。

String [] x = new String[1]; 

someWorkableMethod(new CoolClass() 
{ 
    @Override 
    public void Something(String[] x, String s) { 
    x[0] = s; 
} 
}); 
+0

*新しく宣言されたCoolClassのx [0]は同じスコープにはありません '* - はい、再定義されていない限り入れ子スコープで表示されます –

+0

取り引きは一つです。 CoolClassはシステムクラスであり、メソッドの引数や別のパラメータを変更することはできません。完全なソースの質問 – MrGeorgeous

+0

@MrGeorgeous 'post(...)'は、開発者にとってよく知られている自明の名前を持つ一般的な方法です。 'someMethod()'の後ろでそれを難読化する必要はありません。 –

0

である前に、上記の2行は、簡単な回避策はいくつかのsinchronization技術、電子を使用して同期に非同期createAuth()を回すためにあると呼ばれています。 g。 Semaphore

セマフォ許可証が onSuccess()に解放されるまで
public String createAuth(String login, String password, String device) { 
    //... 
    final String[] res = new String[1]; 
    final Semaphore s = new Semaphore(0); 
    post(BASE_URL, params, new TextHttpResponseHandler() { 
     // ... 

     @Override 
     public void onSuccess(int i, Header[] headers, String s) { 
      Log.d("LoginActivity", s); 
      res[0] = s.toString(); 
      s.release(); // release a permit 
     } 
    }); 

    s.acquire();   // block until permit is available 
    Log.d("LoginActivity", res[0]); 
    return res[0]; 
} 

したがって、createAuth()の実行がブロックされています。その後、res[0]が設定され、安全に読み取られることが保証されます(他のコールバックメソッドが起動されない限り - 確かにs.release()も置く必要があります)。

この解決策は、実行されるスレッドをロックするので、UIスレッドでこれを実行することを強くお勧めします。