我的应用程序遇到了一些问题。我对Android开发很新,所以我希望这是一个容易犯的错误。 所以我正在尝试编写一个通过Wifi(第一个线程)获取一些原始数据的应用程序,进行一些计算(第二个线程),从计算出的数据(第三个线程)中创建一个位图并更新显示(处理程序)。 一些参数由SeekBars调整。一切正常。但有时当我更改seekBarValues时,图片不再更新。线程和处理程序仍在运行,所以我不会收到错误。
这里有一些代码:
MainActivity:
public class MainActivity extends Activity implements OnClickListener {
private Handler outputHandler = new Handler();
private SeekBar seekBarBrightness,
seekBarContrast,
seekBarGamma;
public static volatile double gamma = 1;
public static volatile double brightness = 500;
public static volatile double contrast = 500;
public static volatile double min = 0;
public static volatile double max = 0;
public static volatile boolean isRunning = false;
public static volatile int r = 0;
public static volatile int g = 0;
public static volatile int b = 0;
public static volatile int width = 400;
public static volatile int height = 250;
public volatile double inputExchangeFrame[][ ]= new double[400][250], outputExchangeFrame[][]= new double[400][250];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBarBrightness = (SeekBar) findViewById(R.id.seekBarBrightness);
seekBarContrast = (SeekBar) findViewById(R.id.seekBarContrast);
SeekBarGamma = (SeekBar) findViewById(R.id.seekBarGamma);
newImage = Bitmap.createBitmap(width, height, BitmapConfig.ARGB_8888);
picture.setImageBitmap(newImage);
}
@Override
public void onClick(View v) {
if(v==toggleButtonStartStop){
if(toggleButtonStartStop.isChecked()==true){
isRunning=true;
getFrame();
calculateFrame();
showFrame();
}
else{
isRunning = false;
}
}
}
}
其他方法也在MainACtivity中声明: getFrame()方法:
private synchronized void getFrame(){
inputThread = new Runnable(){
public void run(){
while(isRunning == true){
//inputFrame fron WIFI
inputExchangeFrameLock.lock();
//synchronized(inputExchangeFrame){
for(int x_1=0 ; x_1<width ; x_1++){
for(int y_1=0 ; y_1<height ; y_1++){
inputExchangeFrame[x_1][y_1]=inputFrame[x_1][y_1];
}
}
//}
inputExchangeFrameLock.unlock();
try {
Thread.sleep(120);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};new Thread(inputThread).start();
};
calculateFrame:
private synchronized void calculateFrame(){
calculationThread = new Runnable(){
public void run(){
while(isRunning == true){
//get Data from InputThread to applicate several Filter
inputExchangeFrameLock.lock();
//synchronized(inputExchangeFrame){
for(int x_2=0 ; x_2<width ; x_2++){
for(int y_2=0 ; y_2<height ; y_2++){
calculationFrame[x_2][y_2]=inputExchangeFrame[x_2][y_2];
}
}
//}
inputExchangeFrameLock.unlock();
//Do some calculations on calculationFrame
outputExchangeFrameLock.lock();
//synchronized(outputExchangeFrame){
for(int x_3=0 ; x_3<width ; x_3++){
for(int y_3=0 ; y_3<height ; y_3++){
outputExchangeFrame[x_3][y_3] = calculationFrame[x_3][y_3];
}
}
//}
outputExchangeFrameLock.unlock();
}
}
}; new Thread(calculationThread).start();
};
showFrame():
private synchronized void showFrame(){
outputThread = new Runnable(){
public void
while(isRunning == true){
contrast = seekBarContrast.getProgress() +1;
brightness = seekBarBrightness.getProgress() + 1;
gamma = seekBarGamma.getProgress() + 1;
outputExchangeFrameLock.lock();
//synchronized(outputExchangeFrame){
for(int x_4=0 ; x_4<width ; x_4++){
for(int y_4=0 ; y_4<height ; y_4++){
outputFrame[x_4][y_4] = outputExchangeFrame[x_4][y_4];
}
}
//}
outputExchangeFrameLock.unlock();
for (int x_14=0 ; x_14<width ; x_14++){
for(int y_14=0; y_14<height; y_14++){
//Calculation of r,g,b using gamma, brightness and contrast
}
synchronized(newImage){
newImage.setPixel(x_14, y_14, Color.rgb(r,g,b));
}
}
outputHandler.removeCallbacks(pictureUpdate);
outputHandler.post(pictureUpdate);
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}; new Thread(outputThread).start();
};
和处理程序:
private Runnable pictureUpdate = new Runnable(){
public void run(){ 同步(newImage){ picture.setImageBitmap(newImage);
} }
};
我知道很多文字。但我真的不知道从哪里开始搜索以及如何找到错误。
任何建议都会很棒!
感谢
迈克尔
答案 0 :(得分:3)
您正在实现几个线程,并且您尝试执行的操作的顺序不是确定性的。
例如,可以在getFrame.Runable()。run()之前执行“showFrame.Runable()。run()”。
我的建议是使用AsyncTask,http://developer.android.com/reference/android/os/AsyncTask.html。你可以这样做:
private class ProcessFrameTask extends AsyncTask {
protected void doInBackground(Object... objs) {
getFrame(); // Copy the frame
calculateFrame(); // Do your magic
}
protected void onPostExecute(Long result) {
showFrame(); // Post the result back to main thread
}
}
没有多线程和合作,只有一个Worker线程完成所有工作,并将结果发布回主线程。