AsyncTask和套接字在android java中不起作用

Posted

技术标签:

【中文标题】AsyncTask和套接字在android java中不起作用【英文标题】:AsyncTask and socket not working in android java 【发布时间】:2015-08-12 15:48:55 【问题描述】:

我正在用 java 制作一个简单的应用程序客户端服务器,我希望我的手机能够接收和发送消息到我的电脑,我在同一个局域网上,我的电脑的 ip 是 192.168.1.8,我的 serverSocket 正在端口上运行7777。 由于某种原因,我的客户端 android 无法连接,我认为这是因为我在线程中创建了一个套接字,我已经读过我应该使用 AsyncTask 或 Handle,我也尝试过,但我也遇到了异常。

类服务器:

public class MyServer implements Runnable


private ServerSocket server;
private ObjectInputStream in;
private ObjectOutputStream out;
private Socket clientedConnected;

public ExampleServerZNuC()
    try 
        server= new ServerSocket(7777);
        System.out.println("server opened on port 7777");
     catch (IOException ex) 
        Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
    


public void sendMessage(String message)
    try 
        out.writeObject(message);
        out.flush();
     catch (IOException ex) 
        Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
    

public void sendNotifiy()
  try 
        out.writeObject("Send Notify");
        out.flush();
     catch (IOException ex) 
        Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
    


public String getMessage()
  return "";

public void run()
    System.out.println("method run started");
    System.out.println("Waiting for a client to connect");
    try 
        Socket clientedConnected;
        clientedConnected = server.accept();
        System.out.println("A client connected : "+clientedConnected.getInetAddress().getHostAddress());
        in= new ObjectInputStream(clientedConnected.getInputStream());
        out = new ObjectOutputStream(clientedConnected.getOutputStream());




                 catch (IOException ex) 
        Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
    
    System.out.println("End of method Run");
 

这是我创建运行服务器时得到的输出:

 server opened on port 7777
 method run started
 Waiting for a client to connect

客户端安卓: 连接到我的服务器的类(atm 我只是希望它接收消息):

 import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.OptionalDataException;
 import java.net.Socket;
 import java.net.UnknownHostException;

 import android.util.Log;
 import android.view.View;
 import android.widget.TextView;

public class MyConnect implements Runnable

private Socket myconnect=null ;
private TextView txtMessage;
private ObjectInputStream in; 
private ObjectOutputStream out;
public MyConnect( )
    try 
        // this is my pc's IP, my phone is connected to same LAN
        Log.d("inizializating socket","");
        myconnect= new Socket("192.168.1.8",7777);
        in = new ObjectInputStream(myconnect.getInputStream());
        out = new ObjectOutputStream(myconnect.getOutputStream());
     catch (UnknownHostException e) 
        Log.d("My Error connecting",e.getMessage());
     catch (IOException e) 
        Log.d("My Error connecting",e.getMessage());
    
 
 @Override
 public void run() 
        try 
            String message = (String)in.readObject();
            Log.d("messaged recived",message);
         catch (OptionalDataException e)              
            Log.d("My Error connecting",e.getMessage());
         catch (ClassNotFoundException e) 
            Log.d("Error My ClassNotFoundException",e.getMessage());
         catch (IOException e) 
            Log.d("Error My IOEXCEPTION",e.getMessage());
        





  

 

这是我单击应创建套接字的按钮时遇到的错误: 在创建时我使用 connect=new MyConnect(); 在我使用的 onclick 事件中:

   @Override
   public void onClick(View v) 
    switch(v.getId())
    case R.id.btnExample:


        new Thread(connect).start();

        break;


    


错误信息:

05-29 19:02:05.905: E/AndroidRuntime(6520): FATAL EXCEPTION: main
05-29 19:02:05.905: E/AndroidRuntime(6520):      android.os.NetworkOnMainThreadException
05-29 19:02:05.905: E/AndroidRuntime(6520):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at  libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at libcore.io.IoBridge.connect(IoBridge.java:112)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
 05-29 19:02:05.905: E/AndroidRuntime(6520):    at    java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at java.net.Socket.startupSocket(Socket.java:566)
05-29 19:02:05.905: E/AndroidRuntime(6520):     at java.net.Socket.tryAllAddresses(Socket.java:127)

编辑:

class MySyncTask extends AsyncTask<Integer, Integer, String>
    String advice;
@Override
protected String doInBackground(Integer... params) 

    try 
        s = new Socket("192.168.1.8",7777);
        Log.d("socket connected","");
         ObjectInputStream streamReader = new ObjectInputStream(s.getInputStream()); 

            advice = (String)streamReader.readObject();
     catch (UnknownHostException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (ClassNotFoundException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    

        return "";
    

protected void onPostExecute(String result) 
     txtMessage.setText("you got a message: " + advice);

protected void onPreExecute() 
   Log.d("my started","start");
    


我用过

  MySyncTask asyncTask=new MySyncTask ();
     asyncTask.execute();

onCreate() 方法,但由于某种原因它没有连接到我的服务器

带有 AsyncTask 的 LogCat:

05-29 19:46:21.900: D/my started(26169): start
05-29 19:46:22.020: D/libEGL(26169): loaded /system/lib/egl/l ibEGL_mali.so
05-29 19:46:22.030: D/libEGL(26169): loaded /system/lib/egl/libGLESv1_CM_mali.so
05-29 19:46:22.040: D/libEGL(26169): loaded /system/lib/egl/libGLESv2_mali.so
05-29 19:46:22.080: D/OpenGLRenderer(26169): Enabling debug mode 0

编辑问题已解决

在互联网上搜索为什么套接字无法连接后,我发现有人遇到类似问题,我在这里找到了答案Android Socket not being instantiated 我必须先初始化套接字然后使用连接

【问题讨论】:

如果我在 onCreate() 方法上启动线程也是一样的 【参考方案1】:

这是因为您试图在主线程上执行网络操作。这是一个糟糕的设计,您不想在运行可能需要很长时间才能执行的进程时锁定用户界面。

将您的网络方法放入AsyncTask 或Service。

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> 
     protected Long doInBackground(URL... urls) 
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) 
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         
         return totalSize;
     

     protected void onProgressUpdate(Integer... progress) 
         setProgressPercent(progress[0]);
     

     protected void onPostExecute(Long result) 
         showDialog("Downloaded " + result + " bytes");
     
 

【讨论】:

这应该是评论而不是答案 我尝试了昨天从***.com/questions/20290387/… 读取的 asyncTask,但它现在没有连接到我的服务器 您遇到了什么错误?如果可以,请再次粘贴堆栈跟踪。 我没有收到错误,它只是没有连接,因为在我的服务器上我没有得到输出 System.out.println("A client connected : "+clientedConnected.getInetAddress().getHostAddress( ));它应该在有人连接时打印出来 如果没有错误,就会有异常。在每个 catch 块中返回一个带有 e.getMessage() 的字符串,以便您可以在 onPostExecute 中检查它。【参考方案2】:

就像爱德华多指出的那样,

NetworkOnMainThreadException

当应用程序尝试执行 在其主线程上进行网络操作。

使用Asynctask 进行连接

一定要有

<uses-permission android:name="android.permission.INTERNET" /> 

到你的AndroidManifest.xml

【讨论】:

现在已编辑,我尝试使用 asynctask 但它没有连接到我的服务器 好的,这是另一个问题,请确保您已连接到此 ip“192.168.1.8”和端口“7777” 检查您的 logCat 并向我们展示异常情况,在您的问题中发布@Cosmicluck ! 我确实检查了我的 logCat 并将其发布在这里,我没有例外,它一定是套接字的逻辑问题 确保将 放入您的 AndroidManifest.xml【参考方案3】:

您是否在清单中设置了适当的权限?如果是,手机是否与您的 PC 在同一网络上(如果它们在同一 wifi 网络上是好的)?尝试通过调试器运行并设置断点。

这是一个很好的教程,它解释了 android 中的客户端/服务器通信。 http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/

祝你好运 -拉古

【讨论】:

@Raghu ,我不认为 networkonmainthreadexception 可以抛出,除非一个人没有权限 据我了解,我应该使用 AsyncTask 而不是 Threads 我在客户端上使用 Thread 时出错 我检查了你的一个 cmets,似乎 doInBackground 甚至没有被调用。您可以在创建套接字之前放置一条日志消息以确保是这种情况吗?如果是,这可能就是您定义参数的方式。而不是第一个整数,尝试 Void 因为你没有传递任何参数。 我做了,它没有被调用,但我称之为 onCreate() 这就是我在 OnCreate() 中调用它的方式: MySyncTask asyncTask=new MySyncTask (); asyncTask.execute();

以上是关于AsyncTask和套接字在android java中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

示例:使用AsyncTask的Android双向网络套接字

如何解决替换 AsyncTask 以连接套接字的问题?

如何在 AsyncTask 类中添加更多方法?

如何在 Android 上建立套接字连接

套接字权限 - android清单

第二个 AsyncTask 未执行