在奇怪的代码中访问变量

时间:2016-03-27 15:52:33

标签: java android

我这里有一段奇怪的代码。我也不能说它,因为它被我自己误解了。

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()中将s值写入x [0]? Thanx寻求帮助! )

完整代码,如果需要。

    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]; 
} 
}

3 个答案:

答案 0 :(得分:2)

我认为这是从匿名内部类访问/更改变量的解决方法。你可以改变

String [] x = new String[1];

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

这应该使它可以访问。我个人不喜欢这种方法,有更好的方法可以从匿名函数中设置值。

另外,在使用匿名内部类时要小心,如果它们持续时间超过活动的生命周期,则可能导致活动泄露

修改

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

您在分配之前返回/记录res[0]的值。在http请求完成之前不会调用success(),但在此之前调用上面的两行,并且res[0]为空

答案 1 :(得分:0)

新声明的x[0]中的CoolClass不在同一范围内。如果你想象CoolClass声明在它自己的文件中,这可能更容易概念化。

如果你也传入x字符串数组,这样的东西可能会有效。

String [] x = new String[1];

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

答案 2 :(得分:0)

一个简单的解决方法是使用一些同步技术将异步createAuth()转换为同步,例如: G。 Semaphore

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()的执行被阻止,直到onSuccess()中的信号量许可被释放。之后res[0]保证设置并且可以安全读取(除非触发其他回调方法 - 当然,您还需要将s.release()放在那里)。

由于此解决方案锁定了执行它的线程,因此强烈建议不要在UI线程中运行它。