2013-03-18 28 views
11

Tôi đã thử nghiệm các ví dụ khác nhau để tự làm quen với AsyncTask. Cho đến nay tất cả các ví dụ tôi đã thấy đã có AsyncTask được đưa vào phương thức onCreate của hoạt động chính. Điều mà tôi không thích lắm, vì vậy tôi muốn thấy khó khăn thế nào để tách nó thành lớp riêng của mình. Cho đến nay tôi có điều này:Phát triển Android: Có AsyncTask trong một tệp lớp riêng biệt

các hoạt động chính

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.app.Activity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.asynctaskactivity.ShowDialogAsyncTask; 

public class AsyncTaskActivity extends Activity { 

Button btn_start; 
ProgressBar progressBar; 
TextView txt_percentage; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btn_start = (Button) findViewById(R.id.btn_start); 
     progressBar = (ProgressBar) findViewById(R.id.progress); 
     txt_percentage= (TextView) findViewById(R.id.txt_percentage); 
     Log.v("onCreate","Attempt set up button OnClickListener"); 
     btn_start.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) { 
       btn_start.setEnabled(false); 
       new ShowDialogAsyncTask().execute(); 
      } 
     }); 

     Log.v("onCreate","Success!"); 
    } 
} 

sự riêng biệt lớp AsyncTask mới

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.SystemClock; 
import android.util.Log; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{ 
int progress_status; 

@Override 
    protected void onPreExecute() { 
    // update the UI immediately after the task is executed 
    Log.v("onPreExecute","1"); 
    super.onPreExecute(); 
    Log.v("onPreExecute","2"); 
    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show(); 
    progress_status = 0; 
    Log.v("onPreExecute","3"); 
    txt_percentage.setText("downloading 0%"); 
    Log.v("onPreExecute","4"); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     Log.v("doInBackground","1"); 
     while(progress_status<100){ 

      progress_status += 2; 

      publishProgress(progress_status); 
      SystemClock.sleep(300); 

     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
    super.onProgressUpdate(values); 

    progressBar.setProgress(values[0]); 
    txt_percentage.setText("downloading " +values[0]+"%"); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show(); 

    txt_percentage.setText("download complete"); 
    btn_start.setEnabled(true); 
    } 
} 

Nguyên này là tất cả trong các hoạt động chính, vì thế mà đề cập đến các yếu tố mà asynctask nên trong lý thuyết cập nhật. Rõ ràng hiện nay điều này gây ra lỗi thời gian chạy, điều này khiến tôi suy nghĩ. Làm cách nào để có tệp riêng biệt nhưng vẫn cập nhật chuỗi giao diện người dùng.

Xin lỗi nếu đây là một câu hỏi ngu ngốc, hoàn toàn mới đối với các chủ đề phát triển và chủ đề nền tảng nói riêng.

+0

Trông rất giống với luồng lưu lượng truy cập http: // này.com/questions/6119305/android-how-to-run-asynctask-from-different-class-file – user2070018

+1

Là một sidenote, bạn không cần phải gọi các phương thức siêu trong một 'AsyncTask', chúng không làm gì cả. – nhaarman

+0

Điểm trong chúng thực sự là gì, tôi nhận thấy chúng trong rất nhiều ví dụ về asynctask mà tôi đang xem và không thể tìm ra mục đích của chúng. – cosmicsafari

Trả lời

17

Làm cách nào để có tệp riêng biệt nhưng vẫn cập nhật chuỗi giao diện người dùng.

Okey. Vì vậy, lúc đầu bạn biết rằng lợi thế chính của AsyncTask được thêm vào trong Hoạt động dưới dạng lớp bên trong là bạn có quyền truy cập trực tiếp vào tất cả các phần tử giao diện người dùng và nó có thể làm cho các bản cập nhật giao diện người dùng khá "nhẹ".

Nhưng nếu bạn quyết định làm AsyncTask tách ra khỏi hoạt động (trong đó cũng có một số lợi ích eq code đang sạch hơn và logic ứng dụng được tách ra từ bề ngoài) lớp bạn có thể:

  • Bạn có thể vượt qua các yếu tố giao diện người dùng thông qua constructor của lớp
  • Bạn có thể tạo các bộ định vị khác nhau
  • Bạn có thể tạo một số giao diện sẽ giữ cuộc gọi lại. Hãy xem Android AsyncTask sending Callbacks to UI

Đây là tất cả những gì bạn cần tôi đoán.

8

Thêm giao diện gọi lại và để Activity triển khai.

public interface MyAsyncTaskCallback{ 
    public void onAsyncTaskComplete(); 
} 

Trong postexecute:

myAsyncTaskCallback.onAsyncTaskComplete(); 

Trong constructor của bạn AsyncTask bạn có thể vượt qua thể hiện của MyAsyncTaskCallback (Activity của bạn).

1

Cách xử lý tốt nhất của bạn là thông qua Trình xử lý. Khởi tạo một hoạt động và ghi đè lên phương thức handleMessage(). Khi bạn tạo lớp ShowDialogAsyncTask chỉ cần truyền vào trình xử lý và duy trì một tham chiếu đến nó. Trên postExecute bạn có thể xây dựng một tin nhắn và gửi nó qua phương thức handler sendMessage(). Một câu trả lời tràn ngập được đề cập bằng cách sử dụng một giao diện và một mô hình gọi lại. Điều này sẽ làm việc, tuy nhiên, có một cơ hội mà các hoạt động có thể bị phá hủy và sẽ không có mặt khi phương thức postExecute được thực hiện vì vậy bạn sẽ cần phải kiểm tra cho điều này.

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