Android/Java 传感器 hashCode() 在不同 activity/service 中给出不同的值

Android/Java sensor hashCode() giving different values in distinct activity/service

我有一个使用传感器侦听器的应用程序。基本上,我有一个主要的 activity 是这样的:

MainActivity.java

public class MainActivity extends AppCompatActivity
{
   (...)
   @Override
   protected void onCreate(Bundle savedInstanceState)
   {
      SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

      Log.d(LOG_TAG, "Accelerometer hashCode MA: " + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER).hashCode());
      Log.d(LOG_TAG, "Accelerometer reference MA: " + Integer.toHexString(System.identityHashCode(mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER))));
   }
}

而且我有一个从 MainActivity 启动的服务,如下所示:

startService(new Intent(MainActivity.this, SensorService.class));

我的服务 class 是:

SensorService.java

public class SensorService extends Service implements SensorEventListener, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener
{
   private SensorManager mSensorManager;
   (...)
   @Override
   public int onStartCommand(Intent intent, int flags, int startId)
   {
      mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

      Log.d(LOG_TAG, "Accelerometer hashCode SS: " + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER).hashCode());
      Log.d(LOG_TAG, "Accelerometer reference SS: " + Integer.toHexString(System.identityHashCode(mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER))));
   }
}

当我的智能手机有 Lollipop 时,哈希码的输出在 Activity 和服务中都是相同的。但是,我将我的智能手机更新为 Marshmallow,现在 hashCode 不同了。上面的输出现在总是这样:

加速度计哈希码 MA:262356196

加速度计参考 MA:fa33ce4

加速度计哈希码 SS:26510821

加速度计参考 SS:19485e5

我不明白为什么简单的软件更新会使 hashCode 具有不同的行为,而我需要它们具有相同的行为。你能帮帮我吗?

-- 更新--

我为什么要这个?

在我的 MainActivity 中,我 "printing" 在视图中查看智能手机拥有的所有传感器。这是动态完成的,如下所示:

TextView sensorLayout = new TextView(this);
sensorLayout.setText(sensor.getStringType());
sensorLayout.setId(sensor.hashCode());
sensorLayout.setLayoutParams(new ViewGroup.LayoutParams(
   ViewGroup.LayoutParams.WRAP_CONTENT,
   ViewGroup.LayoutParams.WRAP_CONTENT));

mainLayout.addView(sensorLayout);

那么,SensorService 就是一个侦听器。每次 onSensorChanged() 被调用时,我想通知主要 activity 这个变化,这样我就可以看到新的值。
我这样做是通过广播一个带有两个额外内容的意图(一个带有新值的字符串和一个带有传感器哈希码的整数)。 MainActivity 需要知道它应该更改哪个视图,它是这样完成的:

int hashCode = intent.getIntExtra(SensorService.EXTRA_SENSOR_HASHCODE, 0);
TextView sensorLayout = (TextView) mainLayout.findViewById(hashCode);
sensorLayout.setText(intent.getStringExtra(SensorService.EXTRA_SENSOR_INFO));

身份哈希码始终是默认的 java.lang.Object 实现,即使特定对象的 class 覆盖它并计算不同的哈希码。

身份哈希码不考虑对象的内容,只考虑它所在的位置。普通哈希码可能(应该)考虑内容。因此,每个包含 "hello world" 的两个字符串的标识哈希码将不同,但普通哈希码将相同。

I do so by broadcasting an intent with two extras (a string with the new values and an integer with the hashCode of the sensor).

如果 "broadcasting an intent",你的意思是你在 Context 上调用 sendBroadcast(),请记住,默认情况下你会泄露私人用户数据。即使没有适当的权限,任何应用程序都可以收听您的广播并获取传感器数据。

如果 "broadcasting an intent",你的意思是你在 LocalBroadcastManager 上调用 sendBroadcast(),那么我可以看到三种可能的方法来解决你的问题:

  1. 将其替换为事件总线(例如,greenrobot 的 EventBus),这样您就可以将 Sensor 对象本身传递到 UI 层。

  2. 使用您自己的标识符而不是 hashCode(),因此服务和 activity 可以就如何识别某些特定传感器达成一致。

  3. 删除该服务,让 activity 注册传感器事件本身。

感谢您的帮助。

在我的具体情况下,我决定做一个简单的解决方案:
因为我需要整数形式的散列,所以我使用了 sensor.getType() 函数而不是 sensor.hashCode(),我的问题现在已经解决了!据我在文档中看到的,此方法 returns 智能手机中存在的每个传感器的唯一整数。