【问题标题】:AsyncTask to create a SocketAsyncTask 创建一个 Socket
【发布时间】:2015-07-06 15:06:55
【问题描述】:

我在设置 Socket 连接时遇到了一些问题。

根据我的发现,构造函数Socket(InetAddress dstAddress, int dstPort)不能在main线程中使用。

这是我尝试过的:

CreateSocketTask.java

public class CreateSocketTask extends AsyncTask<InetAddress,Void,Socket>{
<...>

@Override
protected Socket doInBackground(InetAddress... params) {
    try
    {
        socket = new Socket(params[0], port);
        return socket;

    } catch(ConnectException e) {
        Log.e("SocketClient", "Error", e);

        return null;



    } catch(IOException e) {
        Log.e("SocketClient", "Error", e);
        return null;
    }
}

protected void onPostExecute() {
    }
}

然后在我的 SocketClient.java 中:

public class SocketClient implements Runnable{
<...>
public void run()
{
    try
    {
        InetAddress serverAddress = InetAddress.getByName(serverIp);

        new CreateSocketTask().execute(serverAddress);


        try {
        /*Here, I want to retrieve the result of my CreateSocketTask to use it in my new Thread, I tried CreateSocketTask.get() but without any success*/

        new Thread(new SocketReader(new BufferedReader(new InputStreamReader(socket.getInputStream())), observerList)).start();
        }

如何设置套接字连接?


这行得通吗?

我可以简单地创建一个新线程来执行我的 Socket 创建,而不是创建一个服务吗?像这样:

Thread SocketThread =new Thread(new Runnable() {

    @Override
    public void run() {
        try {Socket socket = new Socket(serverAddress,port);}
        catch (IOException e){}
        }
    });
    SocketThread.run();
    try {
    new Thread(new SocketReader(new BufferedReader(new InputStreamReader(socket.getInputStream())), observerList)).start();
    }

【问题讨论】:

  • 你能发布你的整个错误日志吗?
  • 你遇到了什么错误?
  • /*在这里,我想检索我的 CreateSocketTask 的结果以在我的新线程中使用它,我尝试了 CreateSocketTask.get() 但没有任何成功*/。那确实是错误的地方。您应该在 CreateSocketTask 的 onPostExecute 中执行此操作。
  • 我得到一个 android.os.NetworkOnMainThreadException 错误

标签: java android sockets android-asynctask


【解决方案1】:

不要使用 AsyncTask ,这个类的目的是根据“用于短操作(最多几秒钟)”的文档做很少的工作。

所以你最好实现一个服务来处理你的 I/O 请求http://developer.android.com/guide/components/services.html

【讨论】:

  • 异步任务中没有 I/O 请求。只有连接设置。
  • 感谢您的回复。我会研究一下服务解决方案。
【解决方案2】:

当您想使用套接字时,AsyncTask 没有用。当您需要在单独的线程中进行密集工作并最终更改 UI 状态时,您应该使用 AsyncTask。经典应用程序发出 HTTP 请求以从远程服务器检索一些数据,然后更新例如适配器和 UI 组件。

您应该记住,如果您运行该服务,则无论如何都可以使用该服务来执行后台工作,这并不意味着您在单独的线程中进行工作。 文档说

服务在其宿主进程的主线程中运行——该服务不会创建自己的线程,也不会在单独的进程中运行(除非您另外指定)。这意味着,如果您的服务要执行任何 CPU 密集型工作或阻塞操作(例如 MP3 播放或网络),您应该在服务中创建一个新线程来完成这项工作。通过使用单独的线程,您将降低应用程序无响应 (ANR) 错误的风险,并且应用程序的主线程可以保持专用于用户与您的活动的交互。

因此,您必须启动一个单独的线程来处理服务器端并接受连接。每个连接都应该在一个单独的线程中处理,这样您就可以同时拥有多个连接。

同样的概念也适用于客户端。

如果要更新 UI,可以使用回调方法并在主线程中更新 UI。

【讨论】:

  • 我编辑了我的帖子,如果您有任何线索,还有一个问题
【解决方案3】:

问题解决了。

公共类 SocketClient 实现 Runnable 我有方法 public SocketClient(int port, String serverIp, Collection&lt;Observer&gt; observerList, Context context) 我碰巧在其中创建了 socket = new Socket(serverAddress, port)

为了在我的 MapEngine.java 中进行这项工作,我只是添加了

this.SocketClient = new SocketClient(-THEPORT-,-THEIPADDRESS-,null,this)

在我的构造函数中,然后我通过调用

创建了我的套接字
new Thread(SocketClient).start();

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2012-08-19
    相关资源
    最近更新 更多