2010-11-16 13 views
34

Tôi có một ứng dụng thực hiện một số phép tính dài và tôi muốn hiển thị hộp thoại tiến trình trong khi thực hiện xong. Cho đến nay tôi đã tìm thấy rằng tôi có thể làm điều này với các chủ đề/xử lý, nhưng không làm việc, và sau đó tôi phát hiện ra về AsyncTask.Truyền đối số cho AsyncTask và trả về kết quả

Trong ứng dụng của tôi, tôi sử dụng bản đồ có các điểm đánh dấu trên đó và tôi đã triển khai hàm onTap để gọi một phương thức mà tôi đã xác định. Phương thức này tạo một hộp thoại có các nút Có/Không và tôi muốn gọi số AsyncTask nếu Có được nhấp. Câu hỏi của tôi là làm thế nào để vượt qua một ArrayList<String> đến AsyncTask (và làm việc với nó ở đó), và làm thế nào để lấy lại một mới ArrayList<String> như một kết quả từ AsyncTask?

Mã của phương pháp này trông như thế này:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 

ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 

ArrayList<String> result = new ArrayList<String>(); 

new calc_stanica().execute(passing,result); 

String minim = result.get(0); 
int min = Integer.parseInt(minim); 

String glons = result.get(1); 
String glats = result.get(2); 

double glon = Double.parseDouble(glons); 
double glat = Double.parseDouble(glats); 

GeoPoint g = new GeoPoint(glon, glat); 
String korisni_linii = result.get(3); 

Vì vậy, như bạn thấy đấy, tôi xin gửi đến chuỗi array list "đi" vào AsyncTask, và để có được những "kết quả" chuỗi mảng danh sách trở lại từ nó. Và lớp calc_stanica AssycTask trông như thế này:

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 

     //Some calculations... 

     return something; //??? 
    } 

    protected void onPostExecute(Void unused) { 
     dialog.dismiss(); 
    } 

Vì vậy, câu hỏi của tôi là làm thế nào để có được các yếu tố của "đi qua" danh sách mảng trong phương pháp AsyncTask doInBackground (và sử dụng chúng ở đó), và làm thế nào để trả lại một danh sách mảng sử dụng trong phương thức chính (danh sách mảng "kết quả")?

Trả lời

61

Thay đổi phương pháp của bạn trông như thế này:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 
new calc_stanica().execute(passing); //no need to pass in result list 

Và thay đổi async nhiệm vụ thực hiện của bạn

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 
     ArrayList<String> result = new ArrayList<String>(); 
     ArrayList<String> passed = passing[0]; //get passed arraylist 

     //Some calculations... 

     return result; //return result 
    } 

    protected void onPostExecute(ArrayList<String> result) { 
     dialog.dismiss(); 
     String minim = result.get(0); 
     int min = Integer.parseInt(minim); 
     String glons = result.get(1); 
     String glats = result.get(2); 
     double glon = Double.parseDouble(glons); 
     double glat = Double.parseDouble(glats); 
     GeoPoint g = new GeoPoint(glon, glat); 
     String korisni_linii = result.get(3); 
    } 

UPD:

Nếu bạn muốn được tiếp cận với nhiệm vụ bắt đầu từ bối cảnh, cách dễ nhất là ghi đè onPostExecute tại chỗ:

new calc_stanica() { 
    protected void onPostExecute(ArrayList<String> result) { 
     // here you have access to the context in which execute was called in first place. 
     // You'll have to mark all the local variables final though.. 
    } 
}.execute(passing); 
+0

Cảm ơn câu trả lời của bạn, nhưng tôi còn một điều nữa để hỏi. Nếu tôi định nghĩa int min = Integer.parseInt (minim); ví dụ, trong lớp AsyncTask onPostExecute(), làm thế nào tôi có thể truy cập nó từ phương thức lớp chính của tôi? Khi tôi thay đổi nó như thế này, tôi nhận được lỗi "min không thể được giải quyết" trong phương pháp lớp học chính. –

+2

@Bojan Ilievski: Chỉ cần biến min của bạn thành toàn cầu. – Wroclai

+0

Cảm ơn cả hai câu trả lời của bạn một lần nữa, tôi đã giải quyết được vấn đề của mình ... –

12

Tại sao bạn vượt qua một ArrayList ?? Chỉ có thể thực hiện cuộc gọi với các thông số trực tiếp:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
new calc_stanica().execute(itemdesc, curloc) 

Đó là cách thức hoạt động, đúng không? Làm cho một ArrayList để vượt qua biến là làm việc gấp đôi.

+0

Tôi đồng ý với Leander tại đây. Dù sao để thay đổi dấu kiểm chính xác? –

4

Tôi đồng ý với sự kiện này.

gọi:

new calc_stanica().execute(stringList.toArray(new String[stringList.size()])); 

nhiệm vụ:

public class calc_stanica extends AsyncTask<String, Void, ArrayList<String>> { 
     @Override 
     protected ArrayList<String> doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(ArrayList<String> result) { 
      ... //do something with the result list here 
     } 
} 

Hoặc bạn có thể chỉ cần thực hiện danh sách kết quả một tham số lớp và thay thế ArrayList với một boolean (thành công/thất bại);

public class calc_stanica extends AsyncTask<String, Void, Boolean> { 
     private List<String> resultList; 

     @Override 
     protected boolean doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(boolean success) { 
      ... //if successfull, do something with the result list here 
     } 
} 
1

Tôi không làm như vậy. Tôi tìm thấy nó dễ dàng hơn để quá tải các nhà xây dựng của lớp asychtask ..

public class calc_stanica kéo dài AsyncTask>

String String mWhateveryouwantToPass; 

public calc_stanica(String whateveryouwantToPass) 
{ 

    this.String mWhateveryouwantToPass = String whateveryouwantToPass; 
} 
/*Now you can use whateveryouwantToPass in the entire asynchTask ... you could pass in a context to your activity and try that too.*/ ... ... 
0

Bạn có thể nhận được kết quả như vậy trở về: AsyncTask lớp

@Override 
protected Boolean doInBackground(Void... params) { 
    if (host.isEmpty() || dbName.isEmpty() || user.isEmpty() || pass.isEmpty() || port.isEmpty()) { 
     try { 
      throw new SQLException("Database credentials missing"); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    try { 
     Class.forName("org.postgresql.Driver"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 

    try { 
     this.conn = DriverManager.getConnection(this.host + ':' + this.port + '/' + this.dbName, this.user, this.pass); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 

    return true; 
} 

lớp nhận:

_store.execute(); 
boolean result =_store.get(); 

Hy vọng tôi t sẽ giúp.