Android UI,网络和异步代码

时间:2014-07-04 12:36:04

标签: android multithreading networking

我有一个严重的问题,我无法解决问题 我需要对令牌进行身份验证才能让用户登录我的应用程序,问题是即使我使用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);
    }

}

1 个答案:

答案 0 :(得分:0)

您需要使用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
  }
}