2012-10-13 40 views
2

我想制作一个简单的应用程序。在用户看到一个编辑文本的地方..在其中输入一些文本..然后按发送...然后笔记本电脑上的服务器收到该消息。在Android中使用数据报的简单网络连接

现在NetworkOnMainThread异常给我头痛......该应用完全适用于2.3.3,因为当时没有NetworkOnMainThread Exception这样的事情。

已经搜查了很多..有两种解决方案

  1. 制作新的线程联网或
  2. 的AsyncTask。

我试了两个没有任何结果。

尝试1:有独立的线程:

现在我能明白的是,我不得不启动一个单独的线程。好。我做到了。

以下是我的客户端代码。

EditText e ; 
TextView tv; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    e= (EditText) findViewById(R.id.editText1); 
    tv = (TextView) findViewById(R.id.textView1); 
    Thread startNetworking = new Thread(new NetworkThread()); 
    startNetworking.start(); 
} 

public void sendMessage(View v){ 
     if(NetworkThread.sendToClient(e.getText().toString())) 
      tv.setText("Status : Successful"); 
     else 
      tv.setText("Status : Unsuccessful"); 
} 

sendMessage是我发送按钮的onClick函数。我还有一个JAVA文件NetworkThread.java ....

下面是一个代码:

public class NetworkThread implements Runnable{ 

static DatagramSocket socket; 
static InetAddress add; 
public void run() { 
    try { 
     socket = new DatagramSocket(); 
    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     add = InetAddress.getByName("192.168.1.12"); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
public static boolean sendToClient(String message){ 
    DatagramPacket p = new DatagramPacket(message.getBytes(),message.getBytes().length,add,4444); 
    try { 
     socket.send(p); 
     return true; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return false; 
    } 
} 
} 

这仍然无法正常工作。我首先想要耗尽这个第一次尝试,然后我将继续询问关于AsyncTask和我所尝试的内容。所以暂时请帮我实现发送和接收字符串这个简单的任务。

+1

你搜索谷歌在这个话题?这里有很多类似的问题:https://www.google.com/search?q=NetworkOnMainThread+asynctask 例如:https://gist.github.com/3117827 –

+0

是的,我有。但我的问题与AsyncTask,我已经评论下面的答案。如果解决了,那么我很高兴使用AsyncTask。 – PrateekArora

回答

2

不幸的是,在与NetworkThread相同的类中定义sendToClient()并不意味着它将在您的网络特定线程上运行。 sendToClient()方法仍将在您的主(UI)线程上运行,因为它是从onClick()方法中调用的。 UI回调,例如onClick(),总是在UI线程上处理。

我建议使用AsyncTask,因为它使您能够在执行任意数据(例如message参数)之前将背景/网络线程发送到后台/网络线程。继续使用RunnableThread将需要额外的机制来同步UI和网络线程的执行,并且这些挑战在幕后由AsyncTask处理。

+2

你可以在这里找到一个AsyncTask示例:http://stackoverflow.com/questions/9671546/asynctask-android-example –

+0

好的,如果我使用AsyncTask,我不明白的是,我在onClick上给出了这样的声明“ myAsync.execute(new String [] {m​​sg})“?现在每次我点击按钮,AsyncTask创建新的线程?如果是这样,以前的线程呢?它会自动关闭它们吗?另外我会在哪里初始化我的套接字? – PrateekArora

+1

如果您的应用程序有意义,您可以从'onClick'方法启动'AsyncTask'。在Android 3之前。0,'AsyncTask'每次都会创建一个新的线程。在3.0+中,它将重用少量线程,并按顺序处理它们中的每一个。如果要重新使用套接字,则应在“AsyncTask”之外完成套接字初始化。 (或者,您可以在'AsyncTask'内使用[singleton pattern](http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html)。正确答案取决于你的应用程序要求和个人喜好。) – acj