您的位置:首页 > 移动开发 > Android开发

再议Java/Android回调——由一段Bmob查询操作引发的思考

2017-10-26 21:27 483 查看
最近小学弟有一个参赛项目出现个bug解决不了,前来问我。拿来代码一看,有Bmob后端云(PS:什么鬼,好像还不错的样子),其实就是将数据库操作封装过了,使用框架后只需要关注存取对象,不关心增删改查。

他的问题是有一个商品ID,通过商品ID查出拥有该商品的商店后在地图上标注出来(用的高德地图),相关代码如下:

//获取满足条件的所有的商店
private void getShops(Integer productID)
{
final BmobQuery<Shop> shopBmobQuery=new BmobQuery<Shop>();
final BmobQuery<ProductNum> mProductNumquery=new BmobQuery<ProductNum>();
mProductNumquery.addWhereEqualTo("ProID",productID);
mProductNumquery.findObjects(new FindListener<ProductNum>() { // 商品与商店用ProductNum(对象)表关联
@Override
//查询成功调用
public void done(List<ProductNum> list, BmobException e) { // list包含了所有商店ID
if(e==null){
if(list.size()==0){
new AlertDialog.Builder(ShowShop2.this).setTitle("提示")//设置对话框标题
.setMessage("抱歉,没有找到附近有该商品的商店")//设置显示的内容
.setPositiveButton("确定",new DialogInterface.OnClickListener() {//添加确定按钮
@Override
public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件
finish();
}
}).show();
}
//返回查到的商店ID
for(ProductNum productNum:list ){
//查询商店
shopBmobQuery.addWhereEqualTo("ShopID",shopID);
shopBmobQuery.findObjects(new FindListener<Shop>() {
@Override
public void done(List<Shop> list, BmobException e) {// 该list仅有一个元素
for(Shop shop:list) {
if(!showone){ // 第一个商店显示在当前页
showone=true;
displayshopinfo(shop);
getShopInfo(shop);
}
addMarkersToMap(shop); // 给所有商店添加地图标记
}
}
});
}
}else{
Log.i("bmob","失败:"+e.getMessage()+","+e.getErrorCode());
}
}
});

}
代码有点混乱,将就着看吧。他的问题是只能在地图上标记出一个商店(原本可以标记多个),调试插入log发现两次done()回调(此处的ProductNum的list只有两个元素)中的list均只包含同一个Shop(这里指字面值,不是指对象),所以调用addMarkersToMap()方法就只能在地图上标记一个商店。——这是为什么呢?下面看一段代码:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button caller = (Button) findViewById(R.id.caller);
for (int i = 0; i < 2; i++) {
caller.setAlpha(i); // 改变alpha值
caller.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("do some thing");
}
});
}
}

类比上面的代码,caller即是shopBmobQuery,caller.setAlpha()即是shopBmobQuery.addWhereEqualTo(),caller.setOnClickListener()即是shopBmobQuery.findObjects(),onClick()即是done()。caller中两次改变alpha值最终只是作用在一个对象上,设置的OnClickListener也只能是第二个监听器被回调,所以想要两个FindListener监听器被分别回调,必须让shopBmobQuery成为局部变量,即可以生成多个shopBmobQuery对象,分别注册不同的监听器。

所以修改后的代码为:

//查询商店
BmobQuery<Shop> shopBmobQuery = new BmobQuery<Shop>();
shopBmobQuery.addWhereEqualTo("ShopID", local_shopID);
shopBmobQuery.findObjects(new FindListener<Shop>() {
@Override
public void done(List<Shop> list, BmobException e) {
Log.i("Mark", list.toString());
for (Shop shop : list) {
if (!showone) {
showone = true;

displayshopinfo(shop);
getShopInfo(shop);
}
addMarkersToMap(shop);
}
}
});
由此可知,多次注册监听器,只有最终的那个监听器会被回调。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bmob android Java 回调