Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 导致mutableData.setValue()的递归导致在backstack中生成相同的活动?_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Android 导致mutableData.setValue()的递归导致在backstack中生成相同的活动?

Android 导致mutableData.setValue()的递归导致在backstack中生成相同的活动?,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,编辑:2016年10月23日:这一问题尚未解决,我仍在寻找答案。我将重写这个问题,使它更清楚,因为我现在知道是什么导致了这个问题 编辑:2016年10月26日:发现了一些东西:在试图查找问题时,我发现了一个bug,它帮助我找到了一些东西。如果我的Firebase数据库中有以下内容: Campaigns{ UNQ_KEY: 1 //This is being set in the transaction } 而不是这: Campaigns{ UNQ_KEY:{ count:

编辑:2016年10月23日:这一问题尚未解决,我仍在寻找答案。我将重写这个问题,使它更清楚,因为我现在知道是什么导致了这个问题


编辑:2016年10月26日:发现了一些东西:在试图查找问题时,我发现了一个bug,它帮助我找到了一些东西。如果我的Firebase数据库中有以下内容:

Campaigns{
   UNQ_KEY: 1 //This is being set in the transaction
}
而不是这:

Campaigns{
   UNQ_KEY:{
    count: 1 //this is being set in the transaction
  }
}
问题没有发生

总之,这可能是一个递归错误


我有这个Firebase事务:

database.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Long preUserIncrementedInt = Long.parseLong(b.getText().toString());
            Long userIncrementedInt = ++preUserIncrementedInt;
            mutableData.child("users").child(getUid()).child("count").setValue(userIncrementedInt);
            Long preIncrementedTotalCount = mutableData.child("count").getValue(Long.class);
            Long incrementedTotalCount = ++preIncrementedTotalCount;
            mutableData.child("count").setValue(incrementedTotalCount);
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
            if (databaseError != null)
                Log.wtf(TAG,databaseError.getMessage());
        }
    });
此行:

mutableData.child("users").child(getUid()).child("count").setValue(userIncrementedInt);
mutableData.child("count").setValue(incrementedTotalCount);
还有这个:

mutableData.child("users").child(getUid()).child("count").setValue(userIncrementedInt);
mutableData.child("count").setValue(incrementedTotalCount);
当我运行事务时,会再次创建并打开相同的活动。单击“后退”按钮时,它将转到“后退”中的上一个活动。但是,backback中的前一个活动本身就是相同的活动。像这样:

每次单击按钮时,backbackback中都会生成一个新的活动(有问题的活动)

为了向您展示它的外观,这里有一个GIF:


为什么会发生这种情况?

它会重新启动您的活动,因为它在某处崩溃。请尝试以下代码:

public void onClick(View v) {
    if (mp == null){
        mp = new MediaPlayer();
    } else {
        mp.reset();
    }
    try {
        AssetFileDescriptor afd;
        afd = getAssets().openFd("click.mp3");
        mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        mp.prepare();
        mp.start();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e){
    } catch (IOException e){
    } catch (Exception e){
    }
    v.setEnabled(false);
    final View clicked = v;
    Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            clicked.setEnabled(true);
        }
    };
    handler.postAtTime(runnable,System.currentTimeMillis()+100);
    handler.postDelayed(runnable,100);

}
(我将在这里发布,因为它更容易管理我的评论)

未找到解决方案。

*更新4:找到解决方案**

经过多次尝试和大量注释,最终找到了解决方案,显然OP在另一个类中使用了增量方法,并将其移动到用于解决问题的同一个类中

至于为什么会发生这种情况,在我看来,可能与事务的并发性问题有关,可能问题在于它自己在创建一个循环。活动开始后,您实例化了
FirebaseController
,该控制器在某个时候触发了
increment
方法,进行异步执行,最终(以某种方式失败?)再次启动活动



有关失败(但故障排除步骤)的尝试,请参见下文


我试着调试。在这些线路上都没有激活。需要 我需要一堆Android文件(比如View.java)。当我跑向 游标“(跳过下一个调试断点),它将重新启动

是否可以尝试检查runnable中单击的视图是否为空

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // if not null do this
            clicked.setEnabled(true);
            // if null print some log
            // ...
        }
    };
调试时是否使用单步执行或单步执行(如果您深入了解可能使用单步执行(F5)的类的层次结构,是否可以尝试使用单步执行(F6)进行调试)

如果我们找到了答案,我将在这里发布:

更新1:

mutableData.child("users").child(getUid()).child("count").setValue(userIncrementedInt);
mutableData.child("count").setValue(incrementedTotalCount);
MutableData#setValue(java.lang.Object)
说明了这是如何工作的:

将此位置的数据设置为给定值。本地类型 此方法接受对应于JSON类型的值:

Boolean

Long

Double

Map

列表

此外,您可以将自己类的实例设置到此位置,前提是它们满足以下约束:

该类必须具有不接受参数的默认构造函数 类必须为要分配的属性定义公共getter。 没有公共getter的属性将设置为其默认值 当实例被反序列化时

尝试使用其他开发人员建议的其他数据类型:

#setValue
参数更改为上面列表中的一个对象,并返回一个对象,尝试强制转换为正确的类型,也许可以使用
Integer

更新2:

您的数据模式是这样的吗

{
    "campaings": {
        "key": {
            "count": "1",
            "users": {
                "-JRHTHaIs-jNPLXOQivY": {
                    "count": "1",
                    ...
                },
                ...
            }
            ...
        },
        "other-key": {
            ...
        }
        ...
    }
}
这就是我从那里的代码片段推断的,如果我犯了错误,你可以澄清我

// here we are searching for the current reference in Campaings/key
DatabaseReference database = FirebaseDatabase.getInstance().getReference().child("Campaigns").child(key);

int preIncrementUserCount = Integer.parseInt(button.getText().toString());
final int incrementedUserCount = ++preIncrementUserCount;

button.setText(String.valueOf(incrementedUserCount));
database.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {

        // here we are searching for the current count value in 
        // Campaings/key/count
        Integer currentValue = mutableData.child("count").getValue(Integer.class);

        if (currentValue == null) {
            // do something...
        } else {
            // here we are setting the count value in Campaings/key/count
            mutableData.child("count").setValue(++currentValue);
        }

        // here we are setting the count value in Campaings/key/users/UUID/count
        mutableData.child("users").child(getUid()).child("count").setValue(incrementedUserCount);

        return Transaction.success(mutableData);
    }

    @Override
    public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {

       if (databaseError != null) {
            Log.e(TAG, "Error: " + databaseError.getMessage());
       }

       System.out.println("Transaction completed");
    }
});
代码示例的要点是说明您正在执行的数据架构搜索(同样,如果我犯了错误,请在任何部分更正我),但出于调试目的,请将
databaseError
登录到
onComplete

更新3

从:

doTransaction()将被多次调用,并且必须能够 处理空数据。即使远程计算机中存在数据 数据库,当事务运行时,它可能不会在本地缓存 他跑了

尝试更改此部分:

  if (currentValue == null) {
      // do something...
  } else {
      // here we are setting the count value in Campaings/key/count
      mutableData.child("count").setValue(++currentValue);
  }
例如:

  if (mutableData.child("count").getValue() == null) {
      // print something...
      // Log.d(TAG,"Value at some point was null");
      // or maybe (just to test)
      // mutableData.child("count").setValue(1);
  } else {
      // here we are setting the count value in Campaings/key/count
      mutableData.child("count").setValue(++currentValue);
  }

p.S:如果在可预见的未来有任何人可能会对类似的问题进行故障排除,我将离开解决方案

可能是它试图启动未经准备的mediaplayer。这样开始:

 mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
       public void onPrepared(MediaPlayer p){
            p.start();

       }       
 }
编辑:

mutableData.child("users").child(getUid()).child("count").setValue(userIncrementedInt);
mutableData.child("count").setValue(incrementedTotalCount);
看看Firebase MutableData setValue(..)方法,它只接受以下类型。但是你使用int,它是基本类型

  • 布尔值
  • 长的
  • 双重的
  • 地图
  • 名单
所以你应该改变这个

 int totalCount = mutableData.child("count").getValue(int.class);

在这方面,

        mutableData.child("count").setValue(newTotalCount);
 int totalCount = mutableData.child("count").getValue(int.class);
您正在通过setValue()方法传递一个“int”值。它应该是此方法支持的对象

,


您正在通过“int.class”获得价值。它不是一个物体。它也应该是一个对象。改变这个。我希望它能帮助你。

我们能看看活动代码的其余部分吗?@BlackHatSamurai当然可以。只是想确定这不是一个小错误,所以我没有提供完整的代码。给我一个sec@AbAppletic它是否给出任何错误跟踪?或者它只是重新启动而没有任何抱怨?您可以尝试捕获异常并打印它吗?也许是一些错误,而不是在那些3@IvanAlburquerque没有什么。重新启动。完整代码:你能解释一下这有什么不同吗?当我删除所有的
MediaPlayer
东西时,问题仍然存在。奇怪的是,这就解决了。但是,当我调用一个方法(增量)时,它也会重新启动。我会编辑我的问题请通过新的