解决java闭包函数内变量离开闭包函数后无法获取到最终值

来源:互联网 发布:ubuntu命令行调整音量 编辑:程序博客网 时间:2024/05/17 03:03

最近在编一个程序时遇到一个问题,我描述下具体情况,

第一个类

public class EnterActivity extends FragmentActivity {
public void onClick(View v) {
RoomName = a_roomName.getText().toString().trim();
int  RoomNameIsExist =A.newBiludRoom(RoomName);
switch(RoomNameIsExist){
case 1:
add_tipTitleTv.setText(R.string.insertRoomsuccess);
break;
case 0:
add_tipTitleTv.setText(R.string.RoomNameIsnotEmpty);
break;
case -1:
add_tipTitleTv.setText(R.string.erro2);
break;

}
}
}

第二个类

public class A extends BaseActivity {
int returnvalue=0;
public int newBiludRoom(final String RoomName) {
xxx.findObjects(context, new FindListener<Room>() {
public void onSuccess(List<Room> object) {


if (object.isEmpty()) {
returnvalue= 1;
} else {returnvalue= 0;}
}


@Override
public void onError(int code, String msg) {
returnvalue= -1;
}
});
return returnvalue;
}
}

当执行后无论什么情况RoomNameIsExist返回值都为0,分别打印各处的returnvalue,发现xxx.findObjects里的returnvalue是正确的,一旦出了xxx.findObjects函数,returnvalue的值就变为0了。百度了解到xxx.findObjects(context, new FindListener<Room>() {});这种是闭包函数,return returnvalue这句比在xxx.findObjects里为returnvalue赋值先执行,导致直接返回初值0,得不到后续值。这个就似乎涉及值同步问题了


既然了解其原理,若要返回正确的结果,那就必须在findObjects这个闭包函数里返回returnvalue值给调用者,显然直接return returnvalue是不行的。于是 考虑用handler- message或者回调方式可以解决问题。第一个是异步调用,不会阻碍线程;第二个是同步调用,必须等到函数执行完后才会返回,各有利弊吧,要依情况而定。

若是使用handler- message方式的话,就要在主类定义一个Handler,然后将那个handler传到第二个类,然后在xxx.findObjects构建一个message,把值包含在message里,然后sendmessage过去,再在主类的public void handleMessage(Message msg)处理判断返回值。


我是采用回调函数的方式,我的做法是

把 newBiludRoom放到一个类里去,然后在该类中通过接口(interface)来实现定义回调函数

public static class test {

   public MyCallInterface mc;  
 
   public interface MyCallInterface  
   {  
       public void method(int i);    
   } 
   
   public void setCallfuc(MyCallInterface mc)  
   {  
      this.mc= mc;  
   }  
public void newBiludRoom(final String RoomName) {
xxx.findObjects(context, new FindListener<Room>() {
public void onSuccess(List<Room> object) {
if (object.isEmpty()) {mc.method(1);
} else {mc.method(0);}
}

@Override
public void onError(int code, String msg) {mc.method(-1);}
});
}
}


在主类里定义一个类并且使用刚刚定义的接口,用来专门处理返回的信息

public class test2 implements MyCallInterface  
{
public void method(int i)
{
对返回的值进行判断
}
}


主类中调用

test te=new test();
te.setCallfuc(new B());
te.newBiludRoom(RoomName);

这样就能完美地闭包内值的传出来,这就是我现在能够想到的两种方案,若大家有更好的方案也可以交流下,毕竟我刚接触安卓不久,大都数思路都是从其他语言转换而来的大笑

0 0
原创粉丝点击