我有点困惑处理器,AsyncTask和线程之间的区别在Android。我在StackOverflow上读过不少博客和问题。

Handler是后台线程,为您提供与UI通信。例如,更新进度条应该通过Handler来完成。使用Handlers可以获得MessagingQueues的优势,因此如果您想调度消息或更新多个UI元素或有重复任务。

AsyncTask是类似的,事实上,他们利用Handler,但不运行在UI线程,所以它很适合抓取数据,例如抓取web服务。稍后您可以与UI交互。

然而,线程不能与UI交互,提供更多的“基本”线程,你错过了AsyncTask的所有抽象。

但是,我希望在服务中运行套接字连接。这应该运行在一个处理程序或线程,甚至一个AsyncTask?UI交互根本不需要。它对我使用的性能有影响吗?

同时,文档也得到了很大的改进。


当前回答

public class RequestHandler {

    public String sendPostRequest(String requestURL,
                                  HashMap<String, String> postDataParams) {

        URL url;

        StringBuilder sb = new StringBuilder();
        try {
            url = new URL(requestURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(15000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);


            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                sb = new StringBuilder();
                String response;
                while ((response = br.readLine()) != null){
                    sb.append(response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }

}

其他回答

public class RequestHandler {

    public String sendPostRequest(String requestURL,
                                  HashMap<String, String> postDataParams) {

        URL url;

        StringBuilder sb = new StringBuilder();
        try {
            url = new URL(requestURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(15000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);


            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                sb = new StringBuilder();
                String response;
                while ((response = br.readLine()) != null){
                    sb.append(response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }

}

这取决于选择哪一个是基于需求的

Handler主要用于从其他线程切换到主线程,Handler附加到一个循环器,它在队列中发布其可运行任务。 所以如果你已经在其他线程和切换到主线程,那么你需要处理而不是异步任务或其他线程

如果在主线程之外创建的Handler不是一个looper,则不会在线程创建Handler时给出错误,该线程需要被创建为lopper

AsyncTask用于执行在后台线程上运行的代码,并将其结果传递给主线程 ** *异步任务限制 1. 异步任务不附加到活动的生命周期,即使它的活动被破坏,它也会继续运行,而加载器没有这个限制 2. 所有异步任务共享相同的后台线程执行,这也会影响应用程序的性能

线程在应用程序中用于后台工作,但它在主线程上没有任何回调。 如果要求适合一些线程,而不是一个线程,需要给任务很多次,那么线程池执行器是更好的选择。Eg要求图像加载从多个url像滑翔。

线程

当你启动一个应用程序时,会创建一个进程来执行代码。为了有效地利用计算资源,可以在进程内启动线程,以便同时执行多个任务。所以线程允许你通过有效地利用cpu而没有空闲时间来构建高效的应用程序。

在Android中,所有组件都在一个称为主线程的线程上执行。Android系统将任务排队,并在主线程中逐个执行。当长时间运行的任务执行时,应用程序变得无响应。

为了防止这种情况,您可以创建工作线程并运行后台或长时间运行的任务。

由于android使用单线程模型,UI组件是创建非线程安全的,这意味着只有它创建的线程应该访问它们,这意味着UI组件应该只在主线程上更新。由于UI组件运行在主线程上,运行在工作线程上的任务不能修改UI组件。这就是Handler出现的地方。Handler在Looper的帮助下可以连接到新线程或现有线程,并在连接的线程上运行它包含的代码。

处理器使线程间通信成为可能。后台线程可以通过Handler将结果发送给后台线程,连接到主线程的Handler可以更新主线程上的UI组件。

AsyncTask

AsyncTask提供的android使用线程和处理程序,使运行简单的任务在后台和更新结果从后台线程到主线程容易。

请参见android thread, handler, asynctask和线程池的例子。

深入观察之后,事情就一目了然了。

AsyncTask:

这是一种使用线程的简单方法,无需了解任何java线程模型。 AsyncTask给出了各个工作线程和主线程的回调。

用于小的等待操作,如下所示:

从web服务中获取一些数据并在布局中显示。 数据库查询。 当你意识到运行的操作永远不会被嵌套。

处理程序:

当我们在android中安装一个应用程序时,它会为该应用程序创建一个名为MAIN UI thread的线程。所有活动都在该线程中运行。根据android单线程模型规则,我们不能访问UI元素(位图,textview等)直接为另一个线程内定义的活动。

Handler允许你从其他后台线程与UI线程通信。这在android中很有用,因为android不允许其他线程直接与UI线程通信。处理程序可以发送和处理与线程的MessageQueue关联的Message和Runnable对象。每个Handler实例都与单个线程和该线程的消息队列相关联。创建新的Handler时,它将绑定到创建它的线程的线程/消息队列。

它最适合:

它允许您进行消息排队。 消息调度。

线程:

现在是讨论线程的时候了。

线程是AsyncTask和Handler的父线程。它们都在内部使用线程,这意味着您也可以创建自己的线程模型,如AsyncTask和Handler,但这需要对Java的多线程实现有很好的了解。

AsyncTask被设计为在后台执行不超过几秒的操作(不建议从服务器下载兆字节的文件或计算cpu密集型任务,如文件IO操作)。如果您需要执行一个长时间运行的操作,强烈建议您使用java本机线程。Java为您提供了各种与线程相关的类来完成您所需要的工作。使用Handler更新UI线程。