Java 从内部类获取变量的值

Java 从内部类获取变量的值,java,android,retrofit,Java,Android,Retrofit,我有一个在其中实现类的方法: public class RetrofitCallBackUtil { private ArrayList<Message> messages = new ArrayList<>(); public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO

我有一个在其中实现类的方法:

public class RetrofitCallBackUtil {
    private ArrayList<Message> messages = new ArrayList<>();


    public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {
        Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);

        call.enqueue(new Callback<ArrayList<Message>>() {
            @Override
            public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
                if (response.isSuccess()) {
                    messages = response.body();
                    Log.i("Success", "Good ten " + response.body().size());
                } else {
                    Log.i("Success", "Not good  ten" + response.raw());
                }
            }

            @Override
            public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
                Log.i("Fail", "Failure ten " + t.toString());
            }
        });
        //Still get NullPointException from here. (messages.size())
        Log.i("Success", "Good ten activity" + messages.size());
        return messages;
    }

}

因为我想在很多时间和地点使用该方法的结果,所以我希望它返回一个数据。

onResponse
onFailure
是异步调用的,所以当您尝试
返回消息时,尚未更新

从回调中返回它

编辑1:

public void getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {
     Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
     call.enqueue(new Callback<ArrayList<Message>>() {
          @Override
          public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
               if (response.isSuccess()) {
           // THIS IS BEING CALLED AFTER YOUR METHODS RETURNS, SO UPDATE YOUR VIEWS LIKE THIS.

            updateViews(response.body());
            Log.i("Success", "Good ten " + response.body().size());
        } else {
            Log.i("Success", "Not good  ten" + response.raw());
        }
    }

    @Override
    public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
        Log.i("Fail", "Failure ten " + t.toString());
    }
   });


}
public void updateViews(List<Messages> messages){
    //use messages to update your views here.
}
onResponse

updateViews(requestCode, response.body());
并通过比较请求代码相应地更新视图

public void updateViews(int requestCode, List<Messages> messages){
    if(requestCode==XYZ)
    //use messages to update your views here.
}
现在,更改方法定义:

public void getLastTenMessageCallBack(int user_id, ... , final NetworkResponseCallback networkResponseCallback){
执行
onResponse
onFailure

if (response.isSuccess()) {
  if(networkResponseCallback!=null)
       networkResponseCallback.onSuccess(response.body());


public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
    Log.i("Fail", "Failure ten " + t.toString());
    networkResponseCallback.onFailure();
}

onResponse
onFailure
是异步调用的,因此当您尝试
返回消息时,尚未更新

从回调中返回它

编辑1:

public void getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {
     Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
     call.enqueue(new Callback<ArrayList<Message>>() {
          @Override
          public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
               if (response.isSuccess()) {
           // THIS IS BEING CALLED AFTER YOUR METHODS RETURNS, SO UPDATE YOUR VIEWS LIKE THIS.

            updateViews(response.body());
            Log.i("Success", "Good ten " + response.body().size());
        } else {
            Log.i("Success", "Not good  ten" + response.raw());
        }
    }

    @Override
    public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
        Log.i("Fail", "Failure ten " + t.toString());
    }
   });


}
public void updateViews(List<Messages> messages){
    //use messages to update your views here.
}
onResponse

updateViews(requestCode, response.body());
并通过比较请求代码相应地更新视图

public void updateViews(int requestCode, List<Messages> messages){
    if(requestCode==XYZ)
    //use messages to update your views here.
}
现在,更改方法定义:

public void getLastTenMessageCallBack(int user_id, ... , final NetworkResponseCallback networkResponseCallback){
执行
onResponse
onFailure

if (response.isSuccess()) {
  if(networkResponseCallback!=null)
       networkResponseCallback.onSuccess(response.body());


public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
    Log.i("Fail", "Failure ten " + t.toString());
    networkResponseCallback.onFailure();
}

您正在匿名内部类中声明一个名为“messages”的局部作用域变量,该变量将隐藏外部类变量。尝试删除该行并将messages成员变量添加回类对象。

您正在匿名内部类中声明一个名为“messages”的局部作用域变量,该变量将隐藏外部类变量。尝试删除该行并将messages成员变量重新添加到类对象中。

您拥有全局变量的想法是正确的,但您从未为此变量分配任何值,您所做的只是在函数
onResponse()
中声明一个局部变量,此变量的作用域就在该函数的内部
onResponse()
,因此该变量在该函数之外的任何地方都不存在

因此,通过声明一个作用域为封闭类的变量
messages
,您现在可以直接将响应主体分配给“作用域为类的”
messages
变量

这应该可以做到

private List<Message> messages;
public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {
    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {
                // This is wrong you are creating a new variable
                // messages scoped to this function.
                // List<Message>  messages = response.body();
                // Instead just assign the response body to the class
                // scoped variable messages
                messages = response.body();
                Log.i("Success", "Good ten " + response.body().size());
            } else {
                Log.i("Success", "Not good  ten" + response.raw());
            }
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
        }
    });
    Log.i("Success", "Good ten activity" + messages.size());
    return messages;
}
然后将此接口的实现传递给
getLastTenMessageCallBack

public void getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service, final MyCustomCallback callback) {
    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {
                // This is wrong you are creating a new variable
                // messages scoped to this function.
                // List<Message>  messages = response.body();
                // Instead just assign the response body to the class
                // scoped variable messages
                messages = response.body();
                callback.onSuccess(messages);
                Log.i("Success", "Good ten " + response.body().size());
            } else {
                Log.i("Success", "Not good  ten" + response.raw());
            }
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
        }
    });
}

p.S您可以通过在回调接口中使用泛型来进一步完善此功能,就像改型所做的那样。例如,您拥有全局变量的想法是正确的,但您从未为此变量指定任何值,您所做的只是在函数
onResponse()
中声明一个局部变量,此变量的作用域就在该函数的内部
onResponse()
,因此该变量在该函数之外的任何地方都不存在

因此,通过声明一个作用域为封闭类的变量
messages
,您现在可以直接将响应主体分配给“作用域为类的”
messages
变量

这应该可以做到

private List<Message> messages;
public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {
    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {
                // This is wrong you are creating a new variable
                // messages scoped to this function.
                // List<Message>  messages = response.body();
                // Instead just assign the response body to the class
                // scoped variable messages
                messages = response.body();
                Log.i("Success", "Good ten " + response.body().size());
            } else {
                Log.i("Success", "Not good  ten" + response.raw());
            }
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
        }
    });
    Log.i("Success", "Good ten activity" + messages.size());
    return messages;
}
然后将此接口的实现传递给
getLastTenMessageCallBack

public void getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service, final MyCustomCallback callback) {
    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {
                // This is wrong you are creating a new variable
                // messages scoped to this function.
                // List<Message>  messages = response.body();
                // Instead just assign the response body to the class
                // scoped variable messages
                messages = response.body();
                callback.onSuccess(messages);
                Log.i("Success", "Good ten " + response.body().size());
            } else {
                Log.i("Success", "Not good  ten" + response.raw());
            }
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
        }
    });
}
另外,您可以通过在回调接口中使用泛型来进一步细化它,就像改型一样。例如,首先,您的方法
公共ArrayList getLastTenMessageCallBack(…)
具有同步签名,但实现是异步的。所以当方法返回
消息时,它们仍然是空的

使用异步impl的正确签名将是

public void getLastTenMessageCallBack(...)
其中结果只能在回调中获得

如果要使用同步方法,可以使用闩锁:

public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {

    ArrayList<Message> messages = new ArrayList<>();
    CountDownLatch latch = new CountDownLatch(1);

    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {

                messages = response.body();
                latch.countDown();
            } 
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
            latch.countDown();
        }
    });
    //waiting result ...
    latch.await();
    return messages;
}
public ArrayList getLastTenMessageCallBack(int-user\u-id、int-sender\u-id、int-offset\u-number、RESTDatabaseDAO服务){
ArrayList消息=新建ArrayList();
CountDownLatch闩锁=新的CountDownLatch(1);
Call Call=service.getLastTenMessage(用户id、发送者id、偏移量编号);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.issucess()){
messages=response.body();
倒计时();
} 
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.i(“Fail”,“Failure ten”+t.toString());
倒计时();
}
});
//等待结果。。。
satch.wait();
返回消息;
}
注意,没有超出方法范围的变量

upd
如果您想拥有异步方法,并希望从许多类中使用它,该怎么办。正确的签名是:

public void getLastTenMessageCallBack(..., Callback<ArrayList<Message>>)
public void getLastTenMessageCallBack(…,Callback)
您将在客户端代码中实现此回调。当然,异步方法更可取,因此它可以避免ui阻塞首先是您的方法
公共ArrayList getLastTenMessageCallBack(…)
具有同步签名,但实现是异步的。所以当方法返回
消息时,它们仍然是空的

使用异步impl的正确签名将是

public void getLastTenMessageCallBack(...)
其中结果只能在回调中获得

如果要使用同步方法,可以使用闩锁:

public ArrayList<Message> getLastTenMessageCallBack(int user_id, int sender_id, int offset_number, RESTDatabaseDAO service) {

    ArrayList<Message> messages = new ArrayList<>();
    CountDownLatch latch = new CountDownLatch(1);

    Call<ArrayList<Message>> call = service.getLastTenMessage(user_id, sender_id, offset_number);
    call.enqueue(new Callback<ArrayList<Message>>() {
        @Override
        public void onResponse(Call<ArrayList<Message>> call, Response<ArrayList<Message>> response) {
            if (response.isSuccess()) {

                messages = response.body();
                latch.countDown();
            } 
        }

        @Override
        public void onFailure(Call<ArrayList<Message>> call, Throwable t) {
            Log.i("Fail", "Failure ten " + t.toString());
            latch.countDown();
        }
    });
    //waiting result ...
    latch.await();
    return messages;
}
public ArrayList getLastTenMessageCallBack(int-user\u-id、int-sender\u-id、int-offset\u-number、RESTDatabaseDAO服务){
ArrayList消息=新建ArrayList();
CountDownLatch闩锁=新的CountDownLatch(1);
Call Call=service.getLastTenMessage(用户id、发送者id、偏移量编号);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.issucess()){
messages=response.body();
倒计时();
} 
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.i(“Fail”,“Failure ten”+t.toString());
倒计时();
}
});
//等待结果。。。
satch.wait();
返回消息;
}
注意,没有超出方法范围的变量

upd