2013-03-06 26 views
13

Lý do Google sử dụng varargs cho thông số trong AsyncTask là gì? Ví dụ: các phương pháp execute(), doInBackground()publishProgress() tất cả sử dụng ký hiệu [Type]....Mục đích của thông số biến thể AsyncTask

Tôi nghĩ rằng làm cho nó "khó khăn hơn" để sử dụng vì vậy họ phải có một số lý do tốt mà tôi bỏ qua?


Vì vậy, chúng tôi không có tham số, một hoặc nhiều thông số. Hãy phá vỡ nó xuống:

  1. Không thông số (dễ): tham số ParamsVoid và đó là nó. (Các phương pháp không thể sử dụng nó ... vì vậy đó là khá an toàn.)

  2. Một tham số: Ở đây, tôi ít nhất, cảm thấy cần phải làm một kiểm tra vào đầu của phương pháp doInBackground(). Ví dụ, đây là một nhiệm vụ nhận được Integer và tạo ra một kết quả của loại Double:

    public Double doInBackground(Integer... myParameters) { 
        // we are only expecting one parameter 
        if (myParameters.length != 1) 
         throw new IllegalArgumentException("!= 1"); 
    
        return 100d * myParameters[0]; 
    } 
    
  3. Hơn một tham số. Bây giờ ở đây phải là nơi Google đã thực hiện sự lựa chọn đúng đắn? Nhưng như tôi thấy hoặc là bạn quan tâm đến danh sách các thông số của cùng một loại hoặc bạn muốn các loại khác nhau thông số. Google chỉ giải quyết một trong những trường hợp này (với các loại khác nhau, bạn cần một số loại giao diện phổ biến. Trong nhiều trường hợp tôi kết thúc với Object... và đó là không thực sự gõ an toàn ...)


Vì vậy, , vấn đề là gì nếu chúng ta chỉ xóa hoàn toàn varargs? Dưới đây là tập hợp con của các phương thức:

class AsyncTask<Param, Progress, Result> { 

    abstract Result doInBackground(Param param); 
    void publishProgress(Progress progress) { ... } 
} 

Điều này sẽ phù hợp với tất cả các trường hợp trên. Ví dụ, nếu chúng ta muốn xử lý một loạt các thông số chúng ta chỉ có thể sử dụng một loại mảng param:

class MyAsyncTask extends AsyncTask<String[], Integer, String> { 

    String doInBackground(String[] param) { 
     return Arrays.toString(param); 
    } 
} 

Tôi không nhìn thấy khi nó có thể là của bất kỳ sử dụng thực tế. Nhưng tôi chắc chắn rằng tôi đang thiếu một cái gì đó curia mà tôi cần phải biết. :)

+0

thể trùng lặp của [Khi nào bạn sử dụng varargs trong Java?] (Http://stackoverflow.com/questions/766559/when-do-you-use-varargs -in-java) – CommonsWare

+1

Tại sao câu hỏi này trùng lặp với câu hỏi đó? Đó là một giao diện cụ thể mà tôi đang đặt câu hỏi. Tại sao các nhà phát triển sử dụng varargs vấn đề cụ thể này. Tôi nghĩ rằng tôi đã làm rõ rằng tôi biết nó là gì và tôi sử dụng nó khi thích hợp .. :) – dacwe

+0

"Đó là một giao diện cụ thể mà tôi đang đặt câu hỏi" - không có gì trong các đối số của bạn có liên quan đến 'AsyncTask'. Bạn có thể phàn nàn về việc sử dụng varargs với một lớp 'Restaurant'. Nếu câu hỏi của bạn tập trung vào tác động của varargs, ví dụ, cách AsyncTask' xử lý giao tiếp giữa các luồng, thì nó có thể không trùng lặp. Nhưng, như nó đứng, IMHO, các câu trả lời được trình bày trong câu hỏi tôi trích dẫn dường như cũng đề cập đến câu hỏi này. – CommonsWare

Trả lời

1

Tôi nghĩ bạn đúng, cách sử dụng duy nhất của thông số loại Params là trong Params..., ngụ ý rằng nó thực sự là Params[] được yêu cầu ở đây. Tuy nhiên, bây giờ API chỉ hoạt động với các kiểu mảng, nó bỏ qua rất nhiều loại không phải mảng.

Ưu điểm duy nhất của varargs là tại địa điểm cuộc gọi, nhưng nó không phải là nhiều, hoặc -

của Google phiên bản:

AsyncTask<String> task = ... 
task.execute("a", "b"); 

Phiên bản của bạn:

AsyncTask<List<String>> task = ... 
task.execute(Arrays.asList("a", "b")); 
2

Tôi nghĩ rằng các đối số vararg chỉ làm cho nó thuận tiện hơn một chút khi bạn gọi để thực hiện số AsyncTask.

Chừng nào chúng ta đang tự hỏi tại sao AsyncTask được thiết kế theo cách đó là: :-)

Theo tôi, các ParamResult mẫu sẽ không có được thực sự cần thiết để thực hiện như nhau.

Khi bạn viết riêng AsyncTask, bạn phân lớp nó. Thay vì khai báo các kiểu thực tế cho ParamResult, bạn cũng có thể thêm các trường cuối cùng vào lớp con của bạn (Params) và thêm các trường có thể sửa đổi vào lớp con của bạn (Kết quả). Ví dụ:

public class MyAsyncTask extends AsyncTask<Void> { 
    // Input Params 
    private final int inParam1; 
    private final String inParam2; 

    // Output Results 
    private Bitmap resultBitmap; 

    public MyAsyncTask(int param1, String param2) { 
     inParam1 = param1; 
     inParam2 = param2; 
    } 

    @Override 
    protected void doInBackground() { 
     // use param1 and param2 as input to the background process. 
     ... 
     ... 
     // Finished: assign to result 
     resultBitmap = ....; 
    } 

    @Override 
    protected void onPostExecute() { 
     // Send result to UI. 
     ... resultBitmap ... 
     ... 
     resultBitmap = null; 
    } 
} 

Không cần generics, có thể ngoại trừ hiển thị Tiến trình.

Đây là những gì tôi thường làm, đặc biệt nếu kết quả là Bitmap. Giá trị được trả về bởi doInBackground và được xử lý bởi onPostExecute không được đặt thành rỗng sau khi tất cả được đặt và thực hiện và nó lén lút 'rò rỉ' Bitmaps theo cách này (lỗi bộ nhớ do bitmap giữ trong bộ nhớ bằng cách hoàn thành/hoàn thành AsyncTasks).

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