【问题标题】:AsyncTask not returning results right awayAsyncTask 没有立即返回结果
【发布时间】:2012-05-28 07:18:04
【问题描述】:

在阅读了几篇关于 ASYNCTASK 的帖子并在开发者页面上阅读后,我想出了以下代码,并将其分配给一个按钮:

private class TalkToServerTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String response = "";
        try {
            InetAddress serverAddr = InetAddress.getByName(params[0]);
            Socket s = new Socket(serverAddr, Integer.valueOf(params[1]));

            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(s.getOutputStream())), true);

            // WHERE YOU ISSUE THE COMMANDS

            out.println(params[2]);
            // BufferedReader input = new BufferedReader(
            // new InputStreamReader(s.getInputStream()));

            DataInputStream dataInputStream = null;
            dataInputStream = new DataInputStream(s.getInputStream());
            st = dataInputStream.readLine().toString();
            // String st = s.readLine();
            // st = input.readLine();
            // read line(s)

            s.close();
            return st;

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        serverresponse = result;
    }

}

这个想法是,当单击按钮时,ASyncTask 将单词“getDomains”发送到在我的服务器上运行的控制台应用程序,服务器对此进行操作并发送回一个字符串,其中包含在电子邮件中创建的域列表服务器。

我已验证服务器正在接收命令“getdomains”,然后它会回复以管道分隔的域字符串。然而,问题是,我设置了一个 Toast 来弹出套接字事务的结果,而 toast 什么也没显示。如果我再次点击按钮,Toast 会显示域列表。对我来说,似乎套接字首先返回一个空

这里是按钮代码:

case R.id.btnDomains:
            SharedPreferences sp = PreferenceManager
                    .getDefaultSharedPreferences(this);
            IpAddress = sp.getString("ipaddress", "0.0.0.0");
            Serverport = sp.getString("tcpport", "12345");
            buttonpressed = "domains";
            // TalkToServerTask task = new TalkToServerTask();
            new TalkToServerTask().execute(IpAddress, Serverport, "getDomains");

            Intent buttonActivity = new Intent(MainActivity.this, Rules.class);
            buttonActivity.putExtra(MainActivity.DOMAINLIST, serverresponse);

            Toast.makeText(getApplicationContext(), serverresponse,
                    Toast.LENGTH_SHORT).show();

变量“serverresponse”最初显示为空,但随后显示服务器列表。

【问题讨论】:

  • AsyncTask 应该不会立即工作,它应该在单独的线程中工作。您应该从 onPostExecute 更改 UI
  • 为此,建议使用web-service,而不是sockets...

标签: android sockets android-asynctask


【解决方案1】:

正如 Thepoosh 提到的,AsyncTask 正在一个单独的线程上工作。

因此线程正在执行,当你第一次按下按钮时还没有得到结果。

您应该做的是在 onPostExecute 方法中显示数据。此外,您应该将上下文传递给您的 AsyncTask。

public TalkToServerTask(Context context)  {
    this.context = context;
}

@Override
protected void onPostExecute(String result) {
    Intent buttonActivity = new Intent(context, Rules.class);
    buttonActivity.putExtra(MainActivity.DOMAINLIST, result);

    Toast.makeText(context.getApplicationContext(), result, Toast.LENGTH_SHORT).show();
}

【讨论】:

    【解决方案2】:

    你只需要稍微改变你的代码,

    你需要移动这 3 行,

    Intent buttonActivity = new Intent(MainActivity.this, Rules.class); 
    buttonActivity.putExtra(MainActivity.DOMAINLIST, serverresponse); 
    // and also the line to startActivity() as well.
    Toast.makeText(getApplicationContext(), serverresponse, 
                        Toast.LENGTH_SHORT).show(); 
    

    从您的Switch..case 到您写过serverresponse = resultonPostExecute 中的serverresponse = result

    那是因为 AsyncTask 在不同的线程中运行,而您在 Swtich 中执行...情况下,下一行代码不会在 AsyncTask 完成之前执行,所以所有依赖代码都应该写在 onPostExecute的任务。

    【讨论】:

      【解决方案3】:

      AsynTask 在与 UI 线程不同的线程上运行。所以有2个线程并行运行。当您尝试在主 UI 线程上显示列表时,AsynTask 仍在准备获取列表,或者可能在其自己的线程中创建套接字。因此列表数据仍然是空的。

      Asynctaskpostexecute 方法在主 UI 线程上运行,因此在其中更新 UI 是安全且正确的。

      【讨论】:

        猜你喜欢
        • 2012-07-11
        • 1970-01-01
        • 1970-01-01
        • 2014-01-14
        • 2012-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多