2010-01-07 36 views
11

Tôi đang tạo một ứng dụng Android để thực thi các yêu cầu web trong nền và sau đó xử lý dữ liệu đã nhận và sửa đổi giao diện người dùng theo phản hồi của máy chủ.Làm thế nào để thực thi yêu cầu web theo chủ đề của riêng nó?

Mục tiêu của việc gửi yêu cầu và xử lý dữ liệu trong nền là để tránh việc đóng băng giao diện người dùng. Hiện tại tuy nhiên tôi nhận thấy rằng giao diện người dùng đang đóng băng vì vậy tôi không chắc chắn logic đang hoạt động như nó được cho là.

Dưới đây là phần mã mà là vụ phải gửi yêu cầu và xử lý phản hồi trong chủ đề riêng của mình và sau đó vượt qua các dữ liệu vào 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); 
} 

Phương pháp sendRequest() được gọi từ các hoạt động chính mà triển khai ServerResponseHandler. Tôi đoán yêu cầu được thực hiện theo chủ đề của riêng nó và bằng cách gọi

responseHandler.onProductsResponse (sản phẩm);

danh sách sản phẩm (dữ liệu từ web) được chuyển đến hoạt động chính. Dù sao do hiệu suất kém tôi sẽ đánh giá cao nếu có ai có thể sửa bất kỳ vấn đề có thể trong logic ở trên hoặc đề nghị bất kỳ khác (tốt hơn) tùy chọn.

Trả lời

21

Tôi khuyên bạn nên xem ASyncTask class (có sẵn từ Android 1.5).

Nó đơn giản hóa quy trình tạo Chủ đề nền đồng bộ hóa với luồng GUI sau khi hoàn tất.

Bạn sẽ có thể đạt được những gì bạn đang cố gắng sử dụng danh sách một cái gì đó mã này

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 
    } 
} 

Và thực hiện bằng cách gọi

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

Asynctask hoặc handler + thread, tùy thuộc vào bạn Niko – tbruyelle

+2

AsyncTask là cách để thực hiện. –

+0

Đó là giải pháp tốt đẹp – kablu

0

Theo handler javadoc, tôi không nghĩ rằng post() phương pháp tạo bất kỳ chủ đề nào. Nếu tôi đúng, hãy thực hiện Runnable trên luồng mà trình xử lý được đính kèm. Vì vậy, trong trường hợp này, đây là chuỗi hoạt động nên chuỗi giao diện người dùng! Đó là lý do tại sao bạn có hiệu suất kém.

Bạn phải triển khai Thread để thực hiện Runnable của mình. Nhưng bằng cách thực hiện điều đó, bạn sẽ không thể để cập nhật hoạt động của bạn như bạn đang làm bằng cách gọi:

responseHandler.onProductsResponse(products); 

Điều này là do bạn không dùng nữa trong thread UI, và chỉ thread UI được ủy quyền tương tác với giao diện người dùng (do đó hoạt động). Vì vậy, bạn phải thay thế cuộc gọi này bằng cách truy cập vào Handler.

Message msg = handler.obtainMessage(); 
Bundle bundle = new Bundle(); 
bundle.putSerializable("products", products); //not sure it will pass here 
msg.setData(bundle); 
handler.sendMessage(msg); 

Và thực hiện các phương pháp handleMessage() cho Handler của bạn:

@Override 
public void handleMessage(Message msg) 
{ 
    List <Product> products = msg.getData().getSerializable("products"); 
    responseHandler.onProductsResponse(products); 
} 

Cuối cùng nhưng không kém phần quan: các Handler phải vẫn được tạo ra trong các chủ đề hoạt động.

Các vấn đề liên quan