Java 方法在线程上执行-未在完成之前执行/结束
我的android应用程序Java 方法在线程上执行-未在完成之前执行/结束,java,android,multithreading,Java,Android,Multithreading,我的android应用程序主要活动使用了线程,因为使用了一个非常“重”的算法,没有线程,它只会堆叠我的UI和应用程序。 这是我的线程: @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) mGravity = event.values; if (event
主要活动
使用了线程
,因为使用了一个非常“重”的算法,没有线程,它只会堆叠我的UI和应用程序。
这是我的线程
:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth_angle = (float) (orientation[0]*180/Math.PI);
pitch_angle = (float) (orientation[1]*180/Math.PI);
roll_angle = (float) (orientation[2]*180/Math.PI);
p.setText(String.valueOf(pitch_angle));
r.setText(String.valueOf(roll_angle));
y.setText(String.valueOf(azimuth_angle));
new Thread(new Runnable() {
public void run()
{
try
{
Locations = Algo( pitch_angle, roll_angle,
azimuth_angle);
Thread.sleep(500);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
问题:
算法时间约为150-300毫秒。我想在Algo完成之前,这个线程会被再次激活。因为每次运行onsensorchange
时都会执行线程。
我该怎么做才能使Algo按预期将其值返回到“位置”
p.S Algo是在服务上测试的,运行正常。首先,您的位置应该用小写字母书写,因为它是一个变量。其次,如果某个变量被多个线程使用,则必须将其声明为volatile
您可以添加一个volatile布尔值来存储线程状态,例如true正在运行,flase没有。您需要在运行线程之前将此变量设置为true,并在线程中的finally语句中将其设置为false。当此变量的值为true(表示前一个线程正在运行)时,您只需从此方法返回,忽略事件
private volatile boolean heavyAlgRunning = false;
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth_angle = (float) (orientation[0]*180/Math.PI);
pitch_angle = (float) (orientation[1]*180/Math.PI);
roll_angle = (float) (orientation[2]*180/Math.PI);
p.setText(String.valueOf(pitch_angle));
r.setText(String.valueOf(roll_angle));
y.setText(String.valueOf(azimuth_angle));
if (heavyAlgRunning) return;
heavyAlgRunning = true;
new Thread(new Runnable() {
public void run()
{
try
{
Locations = Algo( pitch_angle, roll_angle,
azimuth_angle);
Thread.sleep(500);
}
catch (Throwable e)
{
// TODO Auto-generated catch block
Log.e("t","t",e);
//e.printStackTrace();
}
// finally {
// heavyAlgRunning =false;
// }
heavyAlgRunning =false;
}
}).start();
}
你需要锁定你的线程,直到它完成。因此,您可以尝试在try
语句中添加synchronized
部分,或者使用一个线程系统锁:Anil感谢您提供了这个伟大的解决方案。它起作用了。我可以得到计算出的值并显示它们。我的错误还在于使用一个对象来激活我的算法inter方法,所以我删除了它们。现在这个洞开始工作了,但是速度非常慢。你有什么办法让它快点吗?也许可以为.setText行创建更多线程?我以前删除了它,因为synchronized对我有效。尝试将代码放在新线程上方…
的run
方法中。尽可能多。首先感谢您告诉我视图变量必须使用非大写字母。其次,正如Anil所说,我使用了synchronized,这解决了我的问题。我试着给你加上重格朗宁,它使我的方向成为一个样本,根本不计算算法。你知道为什么吗?只需调试它,似乎最终不会更改heavyAlgRinning。尝试此更改的版本,并在logCatHow come中发布任何异常。它仍然不工作吗?我甚至试着把它放在Algo的末尾和很多地方,然后尝试了你最后的更改,结果仍然是一样的。现在试试看,很快就可以确定运行算法的正确性:)