基本上问题是标题本身的问题,但它遵循上下文。
我正在使用Vuforia库开发一个Android应用程序。此应用程序在每个帧中从相机中获取帧,并与其他信息一起触发 AsyncTask。AsyncTask 的目的是使用这些其他信息并从帧中提取始终对应于我现实世界中同一区域的图像片段(这部分背后的魔力是由于 Vuforia 库并且工作正常(。由于这背后的计算非常耗时,因此任务不会在下一帧之前结束,因此多个 AsyncTask 同时运行,每个 AsyncTask 在不同的帧中开始。从我的测试中,我注意到这些提取的图像片段彼此偏移,这让我认为我在每一帧中执行的不同 AsyncTasks 实例可能正在共享来自局部变量的信息。此信息通过 AsyncTask 构造函数分配给局部变量。
所以我想知道任务是否有可能共享信息,如果是这样,我该如何防止这种情况?
使用 AsyncTask 的构造函数代码进行更新:
GetData 是一个内部类。
private class GetData extends AsyncTask<Matrix34F, Void, Void>{
SampleAppRenderer mRenderer;
float surfaceH, surfaceW, scaleSF;
int imageW, imageH, screenW, screenH, stride;
short[] pixels;
public GetData(SampleAppRenderer mRenderer, float surfaceH, float surfaceW, Image image){
super();
this.mRenderer = mRenderer;
this.surfaceH = surfaceH;
this.surfaceW = surfaceW;
this.imageW = image.getWidth();
this.imageH = image.getHeight();
Vec2I screenDim = mRenderer.getDimensions();
this.screenW = screenDim.getData()[0];
this.screenH = screenDim.getData()[1];
ByteBuffer bb = image.getPixels();
pixels = new short[bb.remaining()/2];
bb.order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(pixels);
this.stride = image.getStride();
this.scaleSF = (float)screenH/imageW;
}
@Override
protected Void doInBackground( Matrix34F... pose){...}
}
我没有复制doInBackground方法的代码,因为它太大了,我认为对于问题目的来说是不必要的。
并在每一帧中调用任务:
//Vuforia's methods to get frame and pose of camera
Frame frame = state.getFrame();
Matrix34F pose = trackableResult.getPose();
for(int i = 0; i < frame.getNumImages(); ++i){
Image image = frame.getImage(i);
GetData ATinstance = new GetData(mSampleAppRenderer, surfaceHeight, surfaceWidth, image);
ATinstance.execute(pose);
}
我不想共享的变量是"图像"和"姿势">
如果您向它们传递相同的引用,它们将共享数据。 例如,如果您有
List myData;
task1 = new AyncTaskClass(myData);
task2 = new AyncTaskClass(myData);
然后任务 1 和任务 2 都将共享 myData。 修复它的方法是制作列表的副本(请注意,如果列表包含对象,则可能需要根据需要制作深层副本(复制其中的每个值(。
局部变量(例如,在doInBacground函数中声明的变量(不共享,每个变量已经有自己的副本。