当前位置: 首页 > 面试题库 >

如何在自己的线程中执行Web请求?

师腾
2023-03-14
问题内容

我正在创建一个Android应用程序,该应用程序必须在后台执行Web请求,然后处理接收到的数据并根据服务器响应修改用户界面。

在后台发布请求和处理数据的目的是避免冻结用户界面。但是目前,我注意到用户界面处于冻结状态,因此我不确定逻辑是否按预期工作。

这是代码的一部分,应该在其自己的线程中发布请求并处理响应,然后将数据传递给GUI:

public class ServerConnection {

Queue<String> requests;

...

DefaultHttpClient httpClient;
HttpHost targetHost;

Handler handler;

ServerResponseHandler responseHandler;
Activity activity;

public ServerConnection(Activity activity){
    this.activity = activity;
    this.responseHandler = (ServerResponseHandler) activity;
    httpClient = new DefaultHttpClient();
    targetHost = new HttpHost(TARGET_DOMAIN, 80, "http");
    requests = new LinkedList<String>();
}



private Runnable requestSender = new Runnable(){

    @Override
    public void run() {
        if(!requests.isEmpty()){
            String requestString = requests.remove();
            HttpGet httpGet = new HttpGet(requestString);
            httpGet.addHeader("Accept", "text/xml");
            String encodingString = "testuser:testpass";
            String sEncodedString = Base64Coder.encodeString(encodingString);

            try{

                String sContent = fetchURL(requestString, sEncodedString);

                XMLParser xmlParser = new XMLParser();

                List <Product> products = xmlParser.getProducts(sContent);

                responseHandler.onProductsResponse(products);
            }
            catch(Exception ex){
                Log.e(TAG, ex.getMessage());
            }
        }
    }
};

public void sendRequest(String requestString){
    requests.add(requestString);
    handler = new Handler();
    handler.post(requestSender);
}

从实现ServerResponseHandler的主要活动中调用sendRequest()方法。我猜想请求是在其自己的线程中执行并通过调用

responseHandler.onProductsResponse(products);

产品列表(来自网络的数据)将传递到主要活动。无论如何,由于性能不佳,如果有人可以纠正以上逻辑中的任何可能的问题或提出其他(更好)的选择,我将不胜感激。


问题答案:

我建议您看一下ASyncTask类(自Android
1.5起可用)。

它简化了创建后台线程的过程,该后台线程在完成后便与GUI线程同步。

您应该能够使用代码列出的内容来实现您正在尝试的功能

private class DownloadFilesTask extends AsyncTask<String, List<Product>, Integer> {
     protected List<Products> doInBackground(String... requestStrings) {
        int count = requestStrings.length;
        int results = 0;
        for (int i = 0; i < count; i++) {
          String requestString = requestStrings[i];
          HttpGet httpGet = new HttpGet(requestString);
          httpGet.addHeader("Accept", "text/xml");
          String encodingString = "testuser:testpass";
          String sEncodedString = Base64Coder.encodeString(encodingString);
          try{
            String sContent = fetchURL(requestString, sEncodedString);
            XMLParser xmlParser = new XMLParser();
            List <Product> products = xmlParser.getProducts(sContent);
            results++;
            publishProgress(products);
          }
          catch(Exception ex){
            Log.e(TAG, ex.getMessage());
          }
        }
        return results;
     }

     protected void onProgressUpdate(Integer... progress) {
         // TODO You are on the GUI thread, and the first element in 
         // the progress parameter contains the last progress
         // published from doInBackground, so update your GUI
     }

     protected void onPostExecute(int result) {
       // Processing is complete, result contains the number of 
       // results you processed
     }
 }

并通过调用执行

new DownloadFilesTask().execute(url1, url2, url3);


 类似资料:
  • 我有一个项目,我需要启动一个GUI,但在另一个不是我的主线程的线程中。 - - - 我的意思是,在任何情况下,我都不能在主线程中启动gui。我需要能够与我的控制器通信(示例中没有控制器)。但当我做正常的事情时:。。开始扩展应用程序{..方法,我无法再与控制器通信,因为线程已被占用。下面的代码应该允许我做我需要做的一切,所以我希望有一种方法可以让它工作。 问题是,为什么我的代码不起作用是一个例外:

  • 问题内容: 我正在学习有关 线程 在。我试图获取正在运行的线程。但是,我无法理解输出的顺序。 以下是我的代码 输出: 谁能帮助我了解输出的顺序。提前致谢。 问题答案: *从本质 *上讲 , 线程 是相互 并发的 。这意味着,两个(或多个)线程在同时执行时会争用同一资源(CPU),并且CPU会按照对您的随机(不可预测)顺序将自己从一个执行切换为另一个执行。您不能也不知道您的CPU和OS体系结构将决定

  • 我有多个带有注释的组件,我看到Spring一次只启动一个组件,即使它们被安排在同一时间运行。

  • 问题内容: 我正在通过BEA Weblogic Server v9.2运行时环境在Eclipse中启动Weblogic应用程序。如果这是直接从命令行运行的,我将执行ctrl- BREAK强制执行线程转储。在Eclipse中有办法吗? 问题答案: 确实(感谢VonC指向SO线程),Dustin在对其消息的评论中指向jstack。 我已经在Eclipse中运行了一个小的Java应用程序(带有GUI),

  • 问题内容: 这是一个简短的问题。在某些时候,我的线程知道应该自杀。最好的方法是什么: Thread.currentThread()。interrupt(); 返回; 顺便说一句,为什么在第一种情况下我们需要使用?是不是指当前线程? 问题答案: 如果要终止 线程 ,则只需返回即可。您不需要调用(尽管它不会做任何坏事。只是您不需要这样做。)这是因为基本上是用来通知线程所有者的(不是,不是100%准确,

  • 问题内容: 我一直在尝试解决涉及使用wait()和notify()的线程通信的问题。基本上我有2个线程T1和T2,我希望它们按以下顺序执行 T1,T2,T1,T2 .....我该如何实现? 实际的问题:有两个线程T1-打印奇数(例如1-100),而T2-打印偶数(1-100)。现在,输出应为1,2,3,4,5,.... 100 问题答案: 您描述了生产者-消费者模式。 它是Java的实现,在许多J