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

最近小学弟有一个参赛项目出现个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);
            }
        }
    });
由此可知,多次注册监听器,只有最终的那个监听器会被回调。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值