2012-05-26 24 views
17

Tôi chỉ đang học về AsyncTask và muốn sử dụng nó như là một lớp riêng biệt, thay vì sau đó là một lớp con.Android, tôi có thể đặt AsyncTask trong một lớp riêng biệt và có gọi lại không?

Ví dụ,

class inetloader extends AsyncTask<String, Void, String> { 


    @Override 
    protected String doInBackground(String... urls) { 

     String response = ""; 

      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(urls[0]); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       InputStream content = execute.getEntity().getContent(); 

       BufferedReader buffer = new BufferedReader(
         new InputStreamReader(content)); 
       String s = ""; 
       while ((s = buffer.readLine()) != null) { 
        response += s; 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     return response; 
    } 


    @Override 
    protected void onPostExecute(String result) { 
     Log.e("xx",result); 
     // how do I pass this result back to the thread, that created me? 
    } 


} 

và chính (ui) chủ đề:

inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 
//il.onResult() 
//{ 
    ///do something... 
//} 

Cảm ơn!

+1

Có, bạn có thể đặt nó trong một lớp học riêng biệt, nhưng hầu hết mọi người không vì nó purpo se thường rõ ràng hơn nếu đó là một lớp bên trong. Nếu bạn định sử dụng lại nó trong nhiều hoạt động, hãy tiếp tục. – keyser

+0

Tôi dự định sử dụng nó cho các mục đích khác nhau, như nếu tôi gọi nó từ đây, kết quả là nó nên làm điều đó và nếu tôi gọi nó từ đó, kết quả là nó nên làm gì đó khác ... nếu tôi sẽ giữ nó trong cùng một lớp và có nó gọi một hàm từ lớp đó trên kết quả, tôi sẽ phải tạo một AsyncTask mới cho mọi loại hành động mà nó phải làm onresult ... –

+0

giao diện sử dụng, chỉ cần triển khai hoạt động của bạn bằng một giao diện và trong onPostExcute() của lớp Asyn gọi mContext.implementedMethod(). –

Trả lời

32

Sử dụng giao diện. Một cái gì đó như:

interface CallBackListener{ 
    public void callback(); 
} 

Sau đó làm điều này trong thread UI của bạn:

inetloader il = new inetloader(); 
li.setListener(this); 
il.execute("http://www.google.com"); 

Trong inetloader, thêm:

CallBackListener mListener; 

    public void setListener(CallBackListener listener){ 
    mListener = listener; 
    } 

sau đó Trong postExecute(), làm:

mListener.callback(); 
+0

Cảm ơn, âm thanh như đó là hướng đi đúng. Đặc biệt là nếu tôi có thể tạo một CallBackListener với bộ nạp vào il = new inetloader(); và chuyển nó vào đối tượng il. –

+0

Hmm ... lạ, tôi không có một "CallBackListener" trong android v3, có thể nó đi theo một số tên khác? –

+3

@RogerTravis Vâng, bạn phải tự tạo giao diện CallBackListener.Và đừng quên thêm "triển khai CallBackLisnter" cho lớp UI chính của bạn. –

1
inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 

String result = il.get();//put it in try-catch 
       ^^^^^^^^ 

here you get result which is in onPostExecute(String result)

+0

Không thực sự: (Tôi cần một số loại trình nghe onResult, điều này sẽ kích hoạt khi AsyncTask hoàn tất, vì việc truy vấn một số máy chủ có thể mất một thời gian. Mặt khác, đặt il.get() vào một vòng lặp while (true) có thể âm thanh quá nguyên thủy, phải không? :) là có bất kỳ lựa chọn tốt hơn? –

+2

@Samir: Đây thực sự là một ý tưởng tồi. Trong khi nó cho phép lấy ra một kết quả từ 'AsyncTask', bằng cách sử dụng phương thức' get() 'sẽ chặn luồng UI và biến một cách hiệu quả những gì nên là một thủ tục không đồng bộ thành một đồng bộ. Việc sử dụng hợp lệ duy nhất cho phương thức 'get()' mà tôi từng đưa ra sẽ là 'chaining' hai 'AsyncTasks'. – Squonk

3

bạn có thể vượt qua các ví dụ hoạt động để xây dựng và gọi chức năng hoạt động từ đó ...
Giống như giao diện sử dụng:

public interface ResultUpdatable { 

    public void setResult(Object obj); 
    } 

Thực hiện này trong hoạt động và vượt qua trong hàm tạo của tác vụ Async và cập nhật kết quả từ onPostExecute sử dụng hàm setResult.

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