【问题标题】:setVisibility() method doesn't work after calling AsyncTask in onResume method in activity/fragment在活动/片段中的 onResume 方法中调用 AsyncTask 后 setVisibility() 方法不起作用
【发布时间】:2018-01-18 18:43:53
【问题描述】:

我在使用 AsyncTask 处理来自服务器的响应时遇到问题:

-> 我有活动。在 onResume() 方法中,我调用我的 AsyncTask 从服务器获取一些数据:

 @Override
     public void onResume() {
        super.onResume();
        //I convey instance of my activity to task, to serve response
        HttpTask httpTask = new HttpTask(this);
        httpTask.execute(url);
 } 

我的活动实现 ServiceCallable 来处理响应:

 public interface ServiceCallable {
    public void onSuccessResponse(Object result);
 }

HttpTask的代码如下:

 public class HttpTask extends AsyncTask<String, Integer, String> {
    private String result = "";
    private ServiceCallable caller;

    public HttpTask(ServiceCallable caller) {
        this.caller = caller;
    }

    @Override
    protected String doInBackground(String... params) {
        URL url;
        HttpURLConnection conn = null;
        try {
            url = new URL(params[0]);
            conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(httpRequestType);
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.connect();

            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                result = readStream(conn.getInputStream());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        caller.onSuccessResponse(result);
    }
 }

然后在我的活动中,我实现了 onSuccessResponse() 方法来处理响应:

 @Override
 public void onSuccessResponse(Object result) {
    //make something with result from service
    //....
    TextView tv = (TextView) findViewById(R.id.myTextView);
    //this doesn't work:
    tv.setVisibility(View.VISIBLE);
 }

我不知道我做错了什么。我确定 httpRequest 工作正常,并且我的活动的 onSuccessResponse 方法被调用。我听说由于从其他线程调用 setVisibility 可能会出错。也许我与我的调用者(ServiceCallable)机制混淆了一些东西。如果有人能指出我应该如何更改我的代码,我将不胜感激。

【问题讨论】:

  • 您究竟想要做什么,因为this doesn't work:
  • 你有错误日志吗?
  • 您可能需要在 UI 线程上设置可见性。
  • "您可能需要在 UI 线程上设置可见性。" -> 如何使用 AsyncTask 做到这一点?
  • "你有错误日志吗?" -> 没有错误日志:即使我将可见性设置为“View.VISIBLE”,我的文本视图仍然不可见。

标签: android multithreading httprequest


【解决方案1】:

如果您确定 onSuccessResponse 被调用,请尝试在 UI 线程上设置可见性:

@Override
public void onSuccessResponse(Object result) {
    TextView tv = (TextView) findViewById(R.id.myTextView);

    YourActivity.runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            tv.setVisibility(View.VISIBLE);
        }
    });
}

【讨论】:

  • 您确认onSuccessResponse 正在执行吗?输入一些Log 消息以跟踪正在发生的事情。
  • 我确定 onSuccessResponse 正在调试中执行
【解决方案2】:

这是我需要添加的。我建议您使用此库 https://github.com/loopj/android-async-http 的其他方式,而不是使用 AsyncTask

AsyncHttpClient client = new AsyncHttpClient();
client.get("https://www.google.com", new AsyncHttpResponseHandler() {

    @Override
    public void onStart() {
        // called before request is started
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // called when response HTTP status is "200 OK"
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // called when response HTTP status is "4XX" (eg. 401, 403, 404)
    }

    @Override
    public void onRetry(int retryNo) {
        // called when request is retried
    }
});

您需要检查清单中的 INTERNET 权限

而你的doInBackground() 需要返回一个字符串

@Override
    protected String doInBackground(String... params) {
        URL url;
        HttpURLConnection conn = null;
        try {
            url = new URL(params[0]);
            conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(httpRequestType);
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.connect();

            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                result = readStream(conn.getInputStream());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return result; // You miss this return
    }

【讨论】:

  • 我开启了互联网权限。添加return语句并不能解决我的问题。
  • 我认为您需要使用 log.d 来检查 asynctask 的哪个步骤已经工作。并且还需要检查 xml 布局。
  • 我建议您使用其他方式从github.com/loopj/android-async-http 的 HTTP 请求中获取内容。我会补充答案
  • 我不知道它如何帮助解决我的问题。正如我所说,请求已正确发送,并且我从服务器收到了正确的答案。它按预期工作。我只想处理该响应并使某些元素可见。
猜你喜欢
  • 2017-08-13
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多