【问题标题】:Asynctask cant display the server responseAsynctask 无法显示服务器响应
【发布时间】:2015-08-01 02:17:15
【问题描述】:

我在 android studio 上创建了一个套接字程序,我想显示服务器的响应。问题是当我使用 textResponse.setText(serverm);它没有用。这是我在 asynctask 上的代码

private class Connect extends AsyncTask<Void, Void, Void> {

    final String address = editTextAddress.getText().toString();


    String textResponse = null;
    String serverm = null;
    @Override
    protected Void doInBackground(Void... params) {
        mRun = true;

            try {
                client = new Socket(address, 3818);
                mBufferIn = new BufferedReader(new InputStreamReader(client.getInputStream()));


                while (mRun) {
                    serverm = mBufferIn.readLine();

                    if (serverm != null) {
                        System.out.println(serverm);
                        textResponse.setText(serverm);


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

}                 

【问题讨论】:

    标签: android sockets android-studio android-asynctask tcpclient


    【解决方案1】:

    什么(可能)错了

    您似乎正在尝试不断地轮询服务器并更新文本字段。 AsyncTask 可能不是实现这一目标的最佳工具选择。 AsyncTasks 的典型用例是您有一个需要很长时间的工作,并且您希望在完成后更新 UI。

    您的代码不起作用的(可能)原因是 AsyncTask 的 doInBackground 方法正在后台线程上运行,但您正在尝试更新 UI textResponse.setText(serverm)。在 Android 上,UI 元素的所有更新都必须发生在“主”或“UI”线程上。您的代码可能会在这一行引发异常并终止 AsyncTask。

    建议

    我认为一个简单的后台线程以及在您有更新时发布到 UI 线程会更自然。使用此方案,您将拥有一个长期存在的线程,您可以在该线程上执行网络,当 UI 需要更新时,该线程将安排在 UI 线程上完成的工作。

    // Create an android.os.Handler that you can use to post Runnables 
    // to the UI thread.
    private static final Handler UI_HANDLER = new Handler(Looper.getMainLooper());
    
    // Create a Runnable that will poll a server and send updates to the
    // UI thread.
    private final Thread mConnectAndPoll = new Thread(new Runnable() {
    
        @Override
        public void run() {
            mRun = true;
            try {
                String address = editTextAddress.getText().toString();
                client = new Socket(address, 3818);
                mBufferIn = new BufferedReader(
                        new InputStreamReader(client.getInputStream()));
    
                while (mRun) {
                    serverm = mBufferIn.readLine();
    
                    if (serverm != null) {
                        System.out.println(serverm);
                        // Create a Runnable that will update the 
                        // textResponse TextView with the response from
                        // the server, and schedule it to run on the UI 
                        // thread.
                        UI_HANDLER.post(new UpdateResponseRunnable(serverm));
                    }
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
    
    // Create a subclass of Runnable that will update textResponse.
    private class UpdateResponseRunnable implements Runnable {
        private final String mValue;
    
        public UpdateResponseRunnable(String value) {
            mValue = value;
        }
    
        @Override
        public void run() {
            textResponse.setText(mValue);
        }
    };
    
    // Start the background thread in onCreate or wherever you are
    // currently starting your AsyncTask.
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
    
        mConnectAndPoll.start();
    }
    

    【讨论】:

    • 我用了这段代码,但是它不起作用,,,,,,创建子类时出现问题。
    • Runnable 没有预期的接口,UpdateTextResponse 是无效的方法声明。我认为这只是一个小问题,但我无法解决。
    • 更新了示例代码。您应该能够通过以下方式修复这些错误:(1) 将 private class UpdateResponseRunnable extends Runnable 更改为 private class UpdateResponseRunnable implements Runnable 和 (2) 将 public UpdateTextResponse 更改为 public UpdateResponseRunnable。
    • 现在没有错误,但是当我将它应用到我的 android 设备时,应用程序崩溃了。我不知道是不是因为我的安卓版本是姜饼。我也尝试在 bluestacks 上模仿它,但我得到了相同的结果。
    • adb logcat 有什么有趣的事情吗?
    【解决方案2】:

    您不应该从 AsyncTask 访问 Activity 级别的实例变量。这可能并且将会导致内存泄漏。

    如果您想要长期运行的后台任务,请查看服务 - 然后使用 LocalBroadcastReceiver 将数据传播回您的活动/相关方。或者您可以使用 Otto 或 GreenRobot 之类的事件总线

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多