模拟器和手机上运行结果竟然不一样!
一个client程序,使用了双线程,一个线程接收server端发送过来的float数组(数组大小为1024),另外一个线程将其打印在手机屏幕上,循环往复。
程序在模拟器上运行很好,server每隔3秒钟产生和发送一次数据,client端也是每隔3秒钟将其打印出来(其实因为屏幕大小限制,只能打印出每个发送过来的float数组的头60个成员)。
但是问题来了,把apk文件安装在手机上之后,运行却出现了这样的问题:在打印完头60个成员,等待下面一个float数组到来之前,竟然又打印了此次接收的数组的别的60个成员(好像是从第700多个开始往后数60个),速度很快,一闪而过,然后就正常打印下面一个到来的数组的头60个成员了,相当于本来在3秒之内应该执行1遍的打印语句执行了2遍,这种情况在程序运行中时而出现时而又没有出现,实在搞不懂怎么回事,为何在模拟器上运行的没问题,到手机上就不行了。
我试着将float数组的大小降到64,就不存在这个问题了,很奇怪。请论坛上各位牛人帮小弟解惑,谢谢~
client代码
- Java code
package com.Shownumbers2; import android.app.Activity;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint; import android.os.Bundle; import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button; import java.io.BufferedInputStream;import java.io.IOException;import java.net.Socket; import java.util.concurrent.Semaphore; class Q { static int x=1024;//设置接收的数据大小,和server端相一致 static float []d=new float[x];//定义一个float数组d,大小为x static byte[] y =new byte[4*x];//定义用来接收数据的byte static float[] a= new float[x]; // Start with consumer semaphore unavailable. static Semaphore semCon = new Semaphore(0); static Semaphore semProd = new Semaphore(1); void pop() {//definition of pop() try { semCon.acquire(); // Acquires a permit from this semaphore, blocking until one is available } catch(InterruptedException e) { System.out.println("InterruptedException caught"); } a=Shownumbers2.bytearrayTofloatarray(y, x);//将产生的数组赋值给a Shownumbers2.Drawtext1(a,x,0);//显示float数组,并打印所花费的时间 semProd.release();//Releases a permit }//end of pop() void push() {//definition of push() try { semProd.acquire(); // Acquires a permit from this semaphore, blocking until one is available } catch(InterruptedException e) { System.out.println("InterruptedException caught"); } //接受socket传来的byte数组 try { Shownumbers2.is = new BufferedInputStream(Shownumbers2.socket.getInputStream()); Shownumbers2.is.read(Q.y); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //startTime= System.currentTimeMillis();//从接收到数据开始计时 semCon.release(); //Releases a permit }//end of push() } //end of Class Q class Producer implements Runnable { //Class Producer get the Object of Q and run the push() Q q; Producer(Q q) { this.q = q; //new Thread(this).start(); } public void run() { while(true){ q.push(); } } }//end of Class Producer class Consumer implements Runnable { //Class Consumer get the Object of Q and run the pop() Q q; Consumer(Q q) { this.q = q; //new Thread(this).start(); } public void run() { while(true){ q.pop(); } } } //end of Class Consumer public class Shownumbers2 extends Activity { /** Called when the activity is first created. */ static Socket socket; static BufferedInputStream is; Button btnDrawText; static SurfaceView sfv; static SurfaceHolder sfh; static Paint paint = new Paint(); Q q = new Q(); Thread C = new Thread( new Consumer(q) ); Thread P = new Thread( new Producer(q)); static Canvas canvas=new Canvas();/*** * 主函数 */ @Override public void onCreate(Bundle savedInstanceState) {//onCreate开始 super.onCreate(savedInstanceState); setContentView(R.layout.main); paint .setColor(Color.GREEN);// green pen sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01); sfh = sfv.getHolder(); btnDrawText = (Button) this.findViewById(R.id.Button01);//加入DrawBall按钮 btnDrawText.setOnClickListener(new Button.OnClickListener() {//设置按钮监听器并设置按下按钮之后的动作 public void onClick(View v) { //创建socket try { socket = new Socket("192.168.1.11",4700); } catch (Exception e) { e.printStackTrace(); } Thread C = new Thread( new Consumer(q) ); Thread P = new Thread( new Producer(q)); C.start(); P.start(); } }); }//主函数结束 /* * 定义绘画函数DrawSin */ static void Drawtext1(float[] a,int x,long time) { canvas = sfh.lockCanvas();// specify a rectangle which will be drawn paint .setAntiAlias(true); canvas.drawColor(Color.BLACK);// clean up the canvas int y=20;//从像素y=20开始 for(int i=0;i<x;i++) { canvas.drawText(""+a[i] , 80 , y, paint); y+=10;//两行之间相隔10个像素点 } canvas.drawText("Time="+time+"ms" , 200 , 70, paint); sfh.unlockCanvasAndPost(canvas);// unlock the canvas and show the drawn picture }//end of Drawtext1() public static float[] bytearrayTofloatarray(byte[] data ,int x) {//将传过来的byte数组恢复成float数组 int [] l= new int[x]; float [] d= new float[x]; int k=0; for(int j=0;j<x;j++){ for (int i=0 ; i < 4; i++) { l[j] <<= 8; l[j] |= (data[k] & 0xff); k+=1; } } for (int i=0;i<x;i++) { d[i] = Float.intBitsToFloat(l[i]); } return d; } }//end of class AndroidSinFinal
[解决办法]
socket发送的数据包过大 会自动分包 分多次发
你发的数据再大些还会超过2次呢