Windows7上的AVD无法连接到Linux服务器



这与我之前的文章有关"http://stackoverflow.com/questions/8788825/linux-udp-server-unreachable-from-window-7",这个问题已经解决了。现在我要开始我最初的工作,将AVD连接到Linux服务器。

我正在使用以下代码连接到服务器

import java.net.*;
class UDPClient {
public final static int DesitnationPort = 9999;
private int mCounter;
private DatagramSocket mClientSocket;
private InetAddress mServerIPAddress;
private byte[] mDataBuffer;
private DatagramPacket mSendPacket;
private DatagramPacket mReceivePacket;
//Constructor
public UDPClient() {
    //Time to make the private data good one
    mCounter =1;
    try {
    mServerIPAddress = InetAddress.getByName("192.168.2.2");
    }
    catch(UnknownHostException e)
    {
        System.out.println("Host cannot be resolved :( ");
    }
    System.out.println("Host has been resolved The IP is valid one ");
    try {
    mClientSocket = new DatagramSocket();
    }
    catch(SocketException e)
    {
        System.out.println("Socket could not be created :( ==> " + e.getMessage());
    }
    System.out.println("Socket has been created ");
    String temp = "This is from the Client == To my Dear Sever :) counter = " + mCounter;
    mDataBuffer = temp.getBytes();
    mSendPacket = new DatagramPacket(mDataBuffer, mDataBuffer.length, mServerIPAddress, DesitnationPort);
    System.out.println("Datagram has been made now ");
    System.out.println("Data ==>"+ mSendPacket.getData());
    System.out.println("Data ==>"+ mSendPacket.getPort());
    System.out.println("Data ==>"+ mSendPacket.getSocketAddress());
    System.out.println("Data ==>"+ mSendPacket.getLength());
}
public void SendDataToServer(){
    try {
            if(!mClientSocket.isClosed())   {
                String temp = "This is from the Client == To my Dear Sever :) counter = " + mCounter;
                mDataBuffer = temp.getBytes();
                mSendPacket = new DatagramPacket(mDataBuffer, mDataBuffer.length, mServerIPAddress, DesitnationPort);           
                mClientSocket.send(mSendPacket);
                System.out.println("Send the packet");
                mCounter++;
            }
            else    {
                System.out.println("Socket is closed");
            }
    }
    catch(Exception e)
    {
        System.out.println("Could not send the data :( ==> " + e.getMessage());
    }
}
public void ReceiveDataFromServer() {
    byte[] tembuff = new byte[1024];
    mReceivePacket = new DatagramPacket(tembuff, tembuff.length);
    try {
            if(!mClientSocket.isClosed())   {
                mClientSocket.receive(mReceivePacket);
            }
            else    {
                System.out.println("Socket is closed");
            }
    }
    catch(Exception e)
    {
        System.out.println("Could not Receive the data :( ");
        return;
    }
        String data = new String(mReceivePacket.getData());
        System.out.println(" Received the Data => " + data);
}
}

当我在java程序中简单地使用类时,这段代码工作得很好,如下所示:-

class TryingWithClient {
public static void main(String a[]) {
    UDPClient mClient = new UDPClient();
    while(true) {
    System.out.println("While Starting");
    mClient.SendDataToServer();
    mClient.ReceiveDataFromServer();
    }
 }
}

当我在AVD项目中使用相同的代码时,我在以下行得到一个Null指针异常:-

public void SendDataToServer(){     
    try {
        if(!mClientSocket.isClosed()){ //<==@ this call Null exception occurs

浏览完互联网&安卓开发网站我得出的结论是,我错过了我添加到我的AVD的GMS/GPS功能。但我对此一无所知。

这是我的代码,它调用了上面的UDPClient。

public class StreamingProjectActivity extends Activity {
/** Called when the activity is first created. */
//All buttons
//private static final String LOG_TAG = "StreamingTest";    
private StreamButton mStreamButton = null;
private UDPClient mClient= null;
class StreamButton extends Button {
    boolean mStartStreaming = true;
    OnClickListener clicker = new OnClickListener() {
        public void onClick(View v) {
            onStream(mStartStreaming);
            if (mStartStreaming) {
                setText("Stop Streaming");
            } else {
                setText("Start recording");
            }
            mStartStreaming = !mStartStreaming;
        }
    };
    public StreamButton(Context ctx) {
        super(ctx);
        setText("Start Streaming");
        setOnClickListener(clicker);
    }
}//class StreamButton Ends
@Override
public void onCreate(Bundle icicle) {
    try {
        mClient = new UDPClient();
        System.out.println("==========> Client created sucessfully :) <====== ");
        super.onCreate(icicle);
        LinearLayout ll = new LinearLayout(this);
        mStreamButton  = new StreamButton(this);
        ll.addView(mStreamButton,
        new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT,
            0));
        setContentView(ll);
        System.out.println("Trying Step 2 now ");
}
catch(Exception e)
{
    System.out.println("Activity could not be launched :( ");   
}
}
//public StreamingTest()
public StreamingProjectActivity(){
System.out.println("Constructor ====>");
System.out.println("Constructor <====");
}//Constructor
private void onStream(boolean start) {
    if (start)
    {
        mClient.SendDataToServer();
        mClient.ReceiveDataFromServer();
        try
          {
            Thread.sleep(4000);  
          }catch (InterruptedException ie)
          {
              System.out.println(ie.getMessage());
          }
    }
 }//onStream
}

请帮忙。

好的,首先:永远不要用System.out.println("some msg " + e.getMessage());打印捕获的异常。请使用Log.e(TAG, "my message", e);。所以你会看到一个堆栈跟踪。

第二:我打赌这段代码会抛出一个错误(检查你是否在LogCat输出中看到了打印):

try {
    mClientSocket = new DatagramSocket();
} catch(SocketException e) {
    System.out.println("Socket could not be created :( ==> " + e.getMessage());
}

这是mClientSocket仍然可能为空的唯一原因。由于这个调用可能会出错,在检查套接字是否关闭之前,应该考虑检查null。

早期解决方案中的问题是;同一线程中的网络操作,称为"StricMode.ThreadPolicy"(尽管,我的问题只是术语中提到的一部分)。

我收到了这些异常"android.os.NetworkOnMainThreadException&android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)",只有在我应用了WarrenFaith的建议后,我才能弄清楚(谢谢Warren)。

这些仅在违反"StricMode"时抛出。

解决方案:只需将UI工作与网络分离即可。我必须为此编写以下代码:

enum ClientThreadStates {
eUndefined,
eStopped,
eRunning,
eIdle,
eSendToServer,
eReadFromServer
}
public class ClientThread extends Thread {
private UDPClient mClient= null;
private ClientThreadStates mStateOfTheThread = ClientThreadStates.eUndefined;
private static String mLOG_TAG; 
public ClientThread(String s){
    mLOG_TAG = s;
    mStateOfTheThread = ClientThreadStates.eStopped;
    mClient = new UDPClient(s);
    start();
}//constructor
public void SetState(ClientThreadStates paramState) {
    mStateOfTheThread = paramState;
}
public ClientThreadStates GetState() {
    return mStateOfTheThread;
}
private void Action(ClientThreadStates s) {
    synchronized(s) {
        switch(mStateOfTheThread)   {
        case eRunning: //fall
        case eIdle: break;
        case eSendToServer: mClient.SendDataToServer(); break;
        case eReadFromServer: mClient.ReceiveDataFromServer(); break;
        }
        try {
            mStateOfTheThread.wait();
        }
        catch( InterruptedException e ){
            Log.e(mLOG_TAG, "Got Exception at wait <==", e);
        }           
    }
}
public void run() {
    mStateOfTheThread = ClientThreadStates.eRunning;
    System.out.println("In Thread.run .. The State is " + mStateOfTheThread);
    while(ClientThreadStates.eStopped.compareTo(mStateOfTheThread) < 0){ //state >stopped
        Action(mStateOfTheThread);
    }//while
}//run
}//class ClientThread

最后在两个线程上同步状态如下:

private void onStream(boolean start) {
    ClientThreadStates State = mClientThread.GetState();
    synchronized(State) {
        if (start)  {
            mClientThread.SetState(ClientThreadStates.eSendToServer);
        }
        else        {
            mClientThread.SetState(ClientThreadStates.eReadFromServer);
        }
        try {               
            State.notify();
        }
        catch( IllegalMonitorStateException  e ) {
                Log.e(LOG_TAG, "Got Exception @ notify <==", e);
        }        
    }
 }//onStream
}//StreamingProjectActivity

现在代码运行得很完美。

谢谢。Ashutosh

最新更新