我有一个使用传感器监听器的应用程序。基本上,我有一个类似这样的主要活动:
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));
我的服务类是:
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时,hashCodes的输出在Activity和Service中都是相同的。但是,我将智能手机更新为Marshmallow,现在hashCode不同了。上面的输出现在总是这样:
Accelerometer hashCode MA:262356196
加速度计参考MA:fa33ce4
Accelerometer hashCode SS:26510821
加速度计参考SS:19485e5
我无法弄清楚为什么简单的软件更新会使hashCodes具有不同的行为,我需要它们具有相同的行为。你能救我吗?
- 更新 -
为什么我要这个?
在我的MainActivity中,我在视图中“打印”了智能手机所具有的所有传感器。这是动态完成的:
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()时,我都想通知此更改的主要活动,以便我可以看到新值。
我这样做是通过广播两个额外的意图(带有新值的字符串和带有传感器的hashCode的整数)。 MainActivity需要知道它应该改变哪个视图,并且这样做是这样的:
int hashCode = intent.getIntExtra(SensorService.EXTRA_SENSOR_HASHCODE, 0);
TextView sensorLayout = (TextView) mainLayout.findViewById(hashCode);
sensorLayout.setText(intent.getStringExtra(SensorService.EXTRA_SENSOR_INFO));
答案 0 :(得分:1)
标识哈希码始终是默认的java.lang.Object实现,即使特定对象的类会覆盖它并计算不同的哈希代码。
标识哈希码不考虑对象的内容,只是它所在的位置。普通哈希码可以(应该)考虑内容。因此,两个字符串的标识哈希码各自包含" hello world"会有所不同,但普通的哈希码会是一样的。
答案 1 :(得分:1)
我这样做是通过广播两个额外的意图(带有新值的字符串和带有传感器的hashCode的整数)。
如果通过“广播意图”,即表示您在sendBroadcast()
上呼叫Context
,请记住默认情况下您正在泄露私人用户数据。即使没有适当的权限,任何应用都可以收听您的广播并获取传感器数据。
如果通过“广播意图”,即表示您在sendBroadcast()
上呼叫LocalBroadcastManager
,那么我可以看到三种可能的方法来解决您的问题:
将其替换为事件总线(例如,greenrobot的EventBus),因此您可以将Sensor
对象本身传递给UI层。
使用您自己的标识符代替hashCode()
,因此服务和活动都可以就如何识别某些特定传感器达成一致。
摆脱服务,让活动注册传感器事件本身。
答案 2 :(得分:0)
感谢您的帮助。
在我的具体案例中,我决定做一个简单的解决方案:
因为我需要以整数形式的哈希,我使用sensor.getType()
函数而不是sensor.hashCode()
,我的问题现在已经解决了!据我在文档中看到,此方法为智能手机中存在的每个传感器返回一个唯一的整数。