【问题标题】:Android UI, Networking and async codeAndroid UI、网络和异步代码
【发布时间】:2014-07-04 12:36:04
【问题描述】:

我有一个无法解决的严重问题。
我需要对令牌进行身份验证才能让用户登录到我的应用程序,问题是即使我使用的是 AsyncTask,并且可能正因为如此,我无法及时对其进行身份验证。有时会出现的其他问题是我收到 NetworkOnMainThreadException 错误......我真的很绝望。

这是流程 -

Check for existsing token -> Validate -> Move to next activity

这是我的代码 -

    public boolean validateToken(TokenAccess token) {
    new IsValid().execute(token);
    return isValid;
}

private class IsValid extends AsyncTask<TokenAccess, Void, Boolean> {

    @Override
    protected Boolean doInBackground(TokenAccess... params) {
        TokenAccess token = params[0];
        switch (token.getSource().getSource()) {
        case 'M':
            new UrlDownloader(new UrlDownloader.DownloadListener() {

                @Override
                public void setRequest(HttpRequest request) {}

                @Override
                public void onRecive(String content) {
                    if (content.contains("stats")) {
                        isValid = true;
                    } else {
                        isValid = false;
                    }

                }

                @Override
                public void onError(Exception e) {}

            }, UrlDownloader.RequestType.GET)
                    .execute("https://api.meetup.com/dashboard?access_token="
                            + token.getToken());
        }
        return isValid;
    }

}

这就是 URLDownloader 类 -

public class UrlDownloader extends AsyncTask<String, Void, HttpResponse> {

    public static final String TAG = "net.ytsweb.socigo.assests.UrlDownloader";

    public enum RequestType {
        GET, POST;
    }

    private RequestType type;
    private DownloadListener listener;

    public UrlDownloader(DownloadListener listener, RequestType type) {
        this.type = type;
        this.listener = listener;
    }

    @Override
    protected HttpResponse doInBackground(String... params) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpUriRequest request;
        HttpResponse response;

        if (type == RequestType.GET) {
            request = new HttpGet(params[0]);
        } else {
            request = new HttpPost(params[1]);
        }
        listener.setRequest(request);
        try {
             response = httpClient.execute(request);
        } catch (Exception e) {
            listener.onError(e);
            return null;
        }

        return response;
    }

    @Override
    protected void onPostExecute(HttpResponse response) {
        try {
            Log.d(TAG, response.getAllHeaders()[0].getValue() + "");
            listener.onRecive(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            listener.onError(e);
        }
    }

    public interface DownloadListener {
        public void onRecive(String content);
        public void onError(Exception e);
        public void setRequest(HttpRequest request);
    }

}

【问题讨论】:

    标签: android multithreading networking


    【解决方案1】:

    您需要使用onPostExecute 来处理IsValid AsyncTask 的结果。我不明白的是:为什么有两个 AsyncTasks?一个就足够了,在那里做所有事情,并在唯一的onPostExecute 中处理结果。

    doInBackground 中发生的任何事情都在单独的线程中,onPostExecute 再次发生在 UI 线程上。一个AsyncTask 就足够了,但不要在validateToken 方法中获取结果。在那里,只需执行您的 AsyncTask 以及您需要对结果执行的任何操作,您必须在 onPostExecute 中启动。

    作为我的意思的一个基本示例:

    public boolean validateToken(TokenAccess token) {
      new YourAsyncTask().execute(token);
      // DON'T rely on a result here
    }
    
    public class YourAsyncTask extends AsyncTask<?, ?, ?> {
    
      @Override
      protected ? doInBackground(?) {
        // do networking in background-task
    
        return result;
      }
    
      @Override
      protected void onPostExecute(? response) {
        // handle result here.. call a method in your main class, a listener with the result, or start an Activity directly
      }
    }
    

    【讨论】:

    • 感谢您的快速回答。我使用了另一个异步任务,因为我认为 UI 异常是因为它。
    • 忘了提一下,我已经制作了某种监听器,它有一个运行 onPostExecute 的函数,即 onRecive 函数。但是我怎样才能从那里返回一个布尔值?
    • 您根本不会“返回”布尔值!只需为您的网络操作执行 AsyncTask,并根据结果显示错误或从您的 onPostExecute 中启动新 Activity(或从那里调用执行此操作的方法/侦听器)。执行时不要依赖 AsyncTask 的返回值。
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多