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()
,那么我可以看到三种可能的方法来解决你的问题:
将其替换为事件总线(例如,greenrobot 的 EventBus),这样您就可以将 Sensor
对象本身传递到 UI 层。
使用您自己的标识符而不是 hashCode()
,因此服务和 activity 可以就如何识别某些特定传感器达成一致。
删除该服务,让 activity 注册传感器事件本身。
感谢您的帮助。
在我的具体情况下,我决定做一个简单的解决方案:
因为我需要整数形式的散列,所以我使用了 sensor.getType()
函数而不是 sensor.hashCode()
,我的问题现在已经解决了!据我在文档中看到的,此方法 returns 智能手机中存在的每个传感器的唯一整数。
我有一个使用传感器侦听器的应用程序。基本上,我有一个主要的 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()
,那么我可以看到三种可能的方法来解决你的问题:
将其替换为事件总线(例如,greenrobot 的 EventBus),这样您就可以将
Sensor
对象本身传递到 UI 层。使用您自己的标识符而不是
hashCode()
,因此服务和 activity 可以就如何识别某些特定传感器达成一致。删除该服务,让 activity 注册传感器事件本身。
感谢您的帮助。
在我的具体情况下,我决定做一个简单的解决方案:
因为我需要整数形式的散列,所以我使用了 sensor.getType()
函数而不是 sensor.hashCode()
,我的问题现在已经解决了!据我在文档中看到的,此方法 returns 智能手机中存在的每个传感器的唯一整数。