2013-03-14 41 views
8

Tôi đã tự hỏi nếu AsyncTask đã được thực hiện để được sử dụng bên trong hoạt động chính (MainActivity.java) đang chạy chuỗi.Tôi có nên sử dụng lớp AsyncTask bên trong Hoạt động mở rộng MainActivity không?

Ví dụ tôi nhận thấy nhiều hướng dẫn khi sử dụng AsyncTask họ khai báo một lớp riêng bên trong những lớp học chính mở rộng Activity hơn là tạo ra một tập tin .java độc lập cho rằng AsyncTask (MyAsyncTask.java) class.

Nhưng tôi nhận thấy rằng khi sử dụng một tập tin độc lập tôi không có khả năng chạy các runOnUIThread() vì nó thuộc về lớp Activity, vì vậy làm thế nào tôi sẽ có thể sử dụng phương pháp này bên trong đó độc lập AsyncTask (MyAsyncTask. java) mở rộng AsyncTask và không phải Activity.

+0

tại sao bạn muốn gọi runOnUIThread từ AsyncTask? – EvilDuck

+0

để thay đổi TextViews, chúng không thể thay đổi từ các chủ đề khác. – Alex

+0

Bạn có thể cập nhật giao diện người dùng trong onPostExecute và onPreExecute –

Trả lời

12

Điều đó hoàn toàn ổn. Tôi làm điều đó thường xuyên nhưng nó phụ thuộc vào cách bạn đang sử dụng nó. Nếu nó có thể được sử dụng bởi othe Activities thì tôi cho nó là lớp riêng hoặc lớp chia sẻ. Nhưng nếu nó là cho một mục đích duy nhất sau đó tôi sẽ làm cho nó một lớp bên trong của MainActivity.

Lợi ích của việc biến nó thành lớp bên trong là nó có quyền truy cập trực tiếp vào các biến thành viên của lớp đó. Nếu bạn làm cho nó một lớp riêng biệt sau đó bạn chỉ cần tạo một constructor cho nó nếu bạn cần phải vượt qua trong params chẳng hạn như một context hoặc các biến khác.

Tôi không biết chính xác bạn đang làm gì nhưng tôi không chắc chắn bạn cần runOnUiThread(). Bạn có thể tạo một hàm tạo trong tệp AsyncTask của mình và yêu cầu nó chấp nhận context làm thông số và bất kỳ thứ gì bạn cần. Sau đó, bạn có thể cập nhật UI trong onPostExecute()

Ví dụ

Public class MyAsyncTask extends AsyncTask 
{ 

private Context context; 

public MyAsyncTask(Context context) { // can take other params if needed 
    this.context = context; 
} 

// Add your AsyncTask methods and logic 
//you can use your context variable in onPostExecute() to manipulate activity UI 
}` 

sau đó gọi nó trong bạn MainActivity

MyAsyncTask myTask = new MyAsyncTask(this); //can pass other variables as needed 
myTask.execute(); 
+0

cảm ơn bạn đã trả lời tôi thích nó, vấn đề là runOnUIThread() không thể chạy nếu nó là một tập tin độc lập, tôi sẽ phải sử dụng nó một lớp bên trong, mà tôi không muốn bởi vì tôi sẽ sử dụng lớp cho 3 hoạt động, và tôi sẽ không đặt toàn bộ đoạn mã của AsyncTask vào mọi hoạt động – Alex

+0

Bạn không phải sử dụng lớp bên trong. Chuyển tham chiếu đến hoạt động dưới dạng tham số trong hàm tạo (giống như codeMagic mô tả). Sau đó sử dụng tham chiếu đến hoạt động để gọi phương thức runOnUIThread() – Sababado

+1

Cảm ơn bạn đã làm việc với onPostExecute()! – Alex

2

Tôi tin rằng trong hầu hết các hướng dẫn họ chọn bất cứ điều gì là đơn giản nhất để hiểu/đọc, không phải cái thực sự là tốt nhất.

Với lớp bên trong, bạn giữ cho các biến của Hoạt động có sẵn, có thể đơn giản hơn.

Nói chung, bạn nên đóng gói càng nhiều càng tốt, cũng như AsyncTask của bạn, để bạn có thể tái sử dụng chúng từ bất kỳ điểm nào khác trong mã của bạn.

+0

có đây là lý do tại sao tôi muốn tạo một tệp độc lập cho nó để tôi có thể sử dụng nó không chỉ cho một mục đích mà còn cho nhiều mục đích quá – Alex

2

Có Bạn có thể tạo AsyncTask class trong số MainActivity.java của mình.

public class CategoryListScreen extends Activity { 


    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
    new loadcategory().execute(); 
} 
class loadcategory extends AsyncTask<Void, Void, Void> { 

@Override 
     protected Void doInBackground(Void... params) { } 

protected void onPostExecute(Void param) { } 
    } // AsyncTask over 
}//main class over 
+0

điều là tôi không muốn sử dụng nó như một lớp bên trong. Tôi muốn sử dụng nó như một lớp riêng biệt. – Alex

4

Nói chung chúng tôi đặt AsyncTask trong cùng một lớp để làm rõ hơn là chỉ được sử dụng bởi cùng một hoạt động.

Nếu bạn muốn điều đó AsyncTask tobe tái sử dụng bởi nhiều hơn một hoạt động hơn, bạn chỉ có thể tạo ra một lớp độc lập và vượt qua các thông số từ hoạt động của nhà thầu

Bạn có thể tạo giao diện trong AsyncTask của bạn để gửi phản hồi từ AsyncTask để hoạt động của bạn như dưới đây và gọi cho bạn phương pháp lister bất cứ khi nào cần thiết.Tôi đã gọi nó là onPostExecute():

public class DeckDownloader extends AsyncTask<Void, Void, String> { 

    OnDownloadUpdateListener listener; 

    public interface OnDownloadUpdateListener { 
     public void OnDownloadDeckFinish(String Response);  
    } 


    public DeckDownloader(Context ctx, OnDownloadUpdateListener listener) { 
     mContext = ctx; 
     this.listener = listener; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
     String str = "downloading"; 
     //your async code goes here 
     return str; 
    } 

    @Override 
    protected void onPreExecute() { 
      super.onPreExecute(); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
      if(listener != null) { 
       listener.OnDownloadDeckProgress(result); 
      } 
    } 
} 

Và trong lớp học Hoạt động của bạn, bạn cần phải thực hiện nghe điều đó và viết mã của bạn để cập nhật TextView trong đó phương pháp thực hiện:

public class myActivity extends Activity{ 
      private DeckDownloader.OnDownloadUpdateListener downloadListener; 
      TextView txtAsyncResponse; 

      @Override 
      public void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       txtAsyncResponse = (TextView) findViewById(R.id.txtAsyncResponse); 


      downloadListener = new DeckDownloader.OnDownloadUpdateListener() { 
       @Override 
       public void OnDownloadDeckFinish(String Response) { 
        txtAsyncResponse.setText(Response); 
       } 
      }; 
    } 

Và bạn có thể viết mã dưới đây để bắt đầu AsyncTask trong hoạt động của bạn bất cứ khi nào được yêu cầu như sự kiện nhấp vào nút hoặc người nào khác

DeckDownloader mTask = new DeckDownloader(this.getApplicationContext(), downloadListener); 
mTask.execute(); 

Đây có thể là thứ bạn muốn!

+0

và làm cách nào tôi có thể thay đổi chế độ xem? Tôi không thể chạy runOnUIThread() nếu nó là một lớp độc lập. – Alex

+0

tại sao bạn sử dụng runOnUIThread? bạn yêu cầu gì? –

+1

Tôi đọc nhận xét của bạn được đề cập là bạn cần thay đổi nội dung văn bản nào trong hoạt động của người gọi sau khi hoàn tất AsyncTask? Tôi hiểu có đúng không? –

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