2013-01-10 19 views
10

Vâng, tôi có một lớp hoạt động với hai nhiệm vụ nền (async-Task) đã được quy định tại hai lớp riêng biệt nhưCách một giao diện có thể được sử dụng cho các tác vụ Android nền khác nhau?

public class GettingBeaconsList extends AsyncTask<String, String, String> 
public class GettingAirports extends AsyncTask<String, String, String> 

được khởi tạo và thực hiện trong MainClass

public class MainClass extends Activity implements DelegateTaskCompleted 
{ 

    int ServiceBoolean = 0; 
    public OnClickListener LoadingBeaconList = new OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      ServiceBoolean =1; 
      new GettingBeaconsList (context,MainClass.this).execute(); 
     } 
    } 

    public OnClickListener LoadingAirportList= new OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      ServiceBoolean =2; 
      new GettingAirports(context,MainClass.this).execute(); 
     } 
    } 


    @Override 
    public void JsonArrayLoaded(JSONArray result) 
    { 
     // bla bla or whatever here i write, does not matter 
     if(ServiceBoolean == 1) { 
       // Load activity 5 
     } 

     else if(ServiceBoolean == 2) 
     { 
      // Load activity 6 

     } 

     else if(ServiceBoolean==3) 
     { 
      // display Toast or Alert Box or load Activity number 8 
     } 


    } 

} 

Bây giờ ở trên mã MainClass.this được lưu trữ dưới dạng Tham chiếu Giao diện trong AsynTask SubClasses như thế này

private Context context    = null; 
private DelegateTaskCompleted delegate  = null; 

public GettingBeaconsList (Context context,DelegateTaskCompleted delegate) 
{ 
    this.context  = context; 
    this.delegate  = delegate; 
} 

// And constructor of second AsynTask is same as of First AsynTask Class 

private Context context    = null; 
private DelegateTaskCompleted delegate  = null; 

public GettingAirports (Context context,DelegateTaskCompleted delegate) 
{ 
    this.context  = context; 
    this.delegate  = delegate; 
} 

onPostExecute của mỗi lớp hoặc lớp con AsynTask, JSONArray được trả về hoặc chuyển về lớp gọi, được hiển thị bên dưới. Trong trường hợp lớp gọi đây là MainClass nhưng có lớp hoạt động khác mà sử dụng lớp AsynTask cùng (GettingBeaconsListGettingAirports)

protected void onPostExecute(String file_url) 
{   
    pDialog.dismiss();  
    delegate.JsonArrayLoaded(gotNearestbeacons); 
} 

Bây giờ tôi có một phương pháp (JsonArrayLoaded) trong MainClass để giải quyết hai phản hồi đến từ hai nhiệm vụ hoặc dịch vụ nền khác nhau. Tôi đang sử dụng điều kiện để tìm ra dịch vụ/lớp hoặc AsynTask được thực thi.

Nhưng tôi yêu cầu cách tốt nhất để xử lý kịch bản như thể chúng ta có 5 dịch vụ nền trở lên trong tương lai và chúng cũng trả về một mảng JSON.

Điều gì sẽ hướng đối tượng ra ngoài trường hợp này?

+2

tên cho giao diện cũng không phù hợp. Hãy làm theo các quy ước đặt tên thích hợp trong khi đăng các ví dụ. –

+2

kết quả được sử dụng trong lớp chính ở đâu? Vui lòng chỉnh sửa bài đăng và đưa ra một ví dụ phù hợp. Không có ý nghĩa –

+1

@MuhammadIrfan Vì vậy, đối với câu hỏi của bạn liên quan đến một __ hướng theo cách_ để giải quyết vấn đề của bạn, bạn đã chọn câu trả lời ít nhất là hướng đối tượng? Tôi muốn nói điều đó thật tuyệt. :) –

Trả lời

7

Giải pháp đơn giản nhất mà tôi có thể nghĩ đến là thay đổi giao diện DelegateTaskCompleted của bạn như vậy vì nó trông như thế này:

public interface DelegateTaskCompleted{ 
    public void JsonArrayLoaded(AsyncTask<String, String, String> task, 
           JSONArray result); 
} 

Sau đó onPostExecute của bạn sẽ gửi chính nó trở lại như dưới đây:

protected void onPostExecute(String file_url) 
{   
    pDialog.dismiss();  
    delegate.JsonArrayLoaded(this, gotNearestbeacons); 
} 

Cuối cùng , trong số MainClass, bạn có thể có séc có điều kiện dựa trên loại AsyncTask:

@Override 
public void JsonArrayLoaded(AsyncTask<String, String, String> task, 
          JSONArray result) 
    { 
     if(task instanceof GettingBeaconsList) { 
       // do stuff related to the beacon list 
     } 

     else if(task instanceof GettingAirports) { 
      // do airport list stuff 
     } 

    } 

Bằng cách đó bạn có thể dễ dàng xác định AsyncTask sẽ gửi thông qua các phản ứng mà không cần phải theo dõi mà nó là, nếu một mất nhiều thời gian hơn so với khác vv


Ngoài ra, có một lớp học kéo dài AsyncTask nhưng thêm một biến trừu tượng để nhận dạng.

public class TrackableAsyncTask extends AsyncTask<String, String, String>{ 
    public abstract int getId(); 

    public static final int ID_AIRPORT = 1; 
    public static final int ID_BEACONS = 2; 
    ... etc 
} 

Sau đó, đặt sân bay và đèn hiệu của bạn AsycTasks mở rộng thay thế này. Điều này sẽ yêu cầu họ triển khai phương thức getId.

public class GettingAirports extends AsyncTask<String, String, String> { 
    public int getId(){ 
     return ID_AIRPORT; 
    } 
} 

Và sau đó thay vì làm một điều kiện if (task instanceof GettingAirports) bạn có thể làm một tuyên bố switch như dưới đây:

switch(task.getId()){ 
    case TrackableAsyncTask.ID_AIRPORT: 
     // run airport code 
} 

Hope this helps.

+0

Bạn có thể mô tả những gì bạn nghĩ là đối tượng định hướng về cách tiếp cận của bạn? Trích dẫn OP: _Điều gì sẽ là cách hướng đối tượng ra trường hợp này? _ –

6

Nếu tôi hiểu vấn đề của bạn chính xác, bạn đã mở rộng AsyncTask một số lần. Mục tiêu của mỗi lớp con này là chuyển một JSONArray đến một Hoạt động thực hiện DelegateTaskCompleted, nơi bạn sẽ làm điều gì đó với nó. Thách thức là "thứ gì đó" mà bạn muốn làm với JSONArray này là khác nhau tùy thuộc vào AsyncTask đã tạo ra nó.

Đi tắt các giả định này, có rất nhiều cách khác nhau mà bạn có thể phân biệt mà AsyncTask các JSONArray đến từ:

  1. Tạo một biến tĩnh, chẳng hạn như một int, trong tập tin lớp DelegateTaskCompleted của bạn đối với từng loại JSONArray nó cần phải xử lý. Thêm thông số vào JsonArrayLoaded cùng loại của biến này. Sau đó, sử dụng các câu lệnh if-else của bạn hoặc một câu lệnh switch để kiểm tra biến này với tập hợp và thực hiện các hành động cho JSONArray của bạn dựa trên nó.
  2. Nếu bạn có quyền truy cập vào bất kỳ thứ gì đang tạo JSONArray, hãy tạo chỉ mục 0 của Mảng chứa thông tin về cách phân tích cú pháp nó. (Có lẽ một cái gì đó bạn có thể so sánh với if-else hoặc switch)
  3. Như bạn đã đề xuất, tạo một giao diện riêng cho mỗi AsyncTask, hoặc một giao diện duy nhất với nhiều phương thức.

Tùy chọn duy nhất 3 là giải pháp hướng đối tượng và như đã được chỉ ra trong các nhận xét chứ không phải là giải pháp tuyệt vời do khả năng mở rộng. Đây không phải là danh sách hoàn chỉnh, chỉ là một vài ý tưởng của tôi.

Tôi tự hỏi, nếu nó đáng để sử dụng Giao diện ở tất cả, hoặc ít nhất theo cách được trình bày.Vì bạn đã có các lớp con khác của AsyncTask để xử lý việc tạo các JSONArrays, tại sao không làm bất cứ điều gì bạn đang làm với chúng trong phương thức doInBackground() khỏi chủ đề chính, hoặc ít nhất là đặt logic ở đâu đó trong các lớp đó, và trả lại kết quả (hoặc có thể nhồi chúng vào một cơ sở dữ liệu và nhận chúng khi cần). Tôi nghĩ rằng có thể có cách tốt hơn để xử lý thừa kế AsyncTask của bạn tránh giao diện tất cả cùng nhau hoặc ít nhất sử dụng chúng theo cách khác nhau, chẳng hạn như một Giao diện duy nhất được thực hiện bởi tất cả các AsyncTask của bạn. Sẽ rất hữu ích nếu bạn có thể làm rõ câu hỏi của mình và giải thích loại hoạt động cả AsyncTasks và phương thức JSONArrayLoaded của bạn đang hoạt động và có lẽ lý do của bạn để sử dụng Giao diện theo cách của bạn. Thật khó để đưa ra một câu trả lời hoặc lời khuyên OO cụ thể về các thực hành tốt nhất của OO với rất ít thông tin về những gì mã của bạn thực sự đang làm và hy vọng đạt được.

+0

Tôi đang tìm nạp bản ghi từ cơ sở dữ liệu ở định dạng json trong doInBackground(). AysnTask khác nhau tìm nạp các bản ghi khác nhau như JSONArray. –

+0

Giao diện được sử dụng vì có các lớp hoạt động khác sử dụng cùng AsynTask để tạo AsynTask chung chung. phương thức onPostExecute, tôi sử dụng delegate.JsonArrayLoaded (gotNearestbeacons); đại biểu là một giao diện đại diện cho tất cả các lớp hoạt động ở đây. –

+0

JSONArrayLoaded thực hiện các thao tác khác nhau. Tôi đã sửa đổi một câu hỏi ở phần này –

12

Hi mã này sẽ giúp bạn

Đây là giao diện cho callback

public interface CallbackReceiver { 
    public void receiveData(Object result); 

} 

sử dụng AsyncTask lớp như Abstract class

public abstract class JsonDataCallback extends AsyncTask<String, String, String> implements CallbackReceiver { 
private ProgressDialog mProgressDialog; 
Handler handler; 
Runnable callback; 
Activity activity; 


public JsonDataCallback(Activity activity) 
{ 
    this.activity=activity; 
    mProgressDialog = new ProgressDialog(activity); 
    mProgressDialog.setMessage("Loading Please Wait."); 
    mProgressDialog.setIndeterminate(false); 
    mProgressDialog.setMax(100); 
    mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
    mProgressDialog.setCancelable(true); 
} 

public abstract void receiveData(Object object); 
@Override 
protected void onPreExecute() { 
    mProgressDialog =ProgressDialog.show(activity, "", "Please Wait",true,false); 
    super.onPreExecute(); 
} 

@Override 
protected String doInBackground(String... aurl) { 
    String results=""; 
    // do stuff 
    return results; 
} 


@Override 
protected void onPostExecute(String jsonData) { 
    if (mProgressDialog != null || mProgressDialog.isShowing()){ 
     mProgressDialog.dismiss(); 
} 
    if(jsonData!=null) 
    { 
     receiveData(jsonData); 
    } 
} 
} 

Và trong mã của bạn sử dụng nó như

này
String url = ipaddress + "/GrantAdvanceList; 
      JsonDataCallback callbackservice = new JsonDataCallback(yourActivity.this) { 
       @Override 
       public void receiveData(Object object) { 
        jsonRecordsData = (String)object; 
        //do stuff with call back data 
       } 
      }; 

     callbackservice.execute(url, null, null); 

bạn có thể tái sử dụng mã theo cách này, tôi hy vọng điều này sẽ giúp bạn. Cảm ơn trước.

6

Bạn cũng có thể xem xét xử lý để đạt được điều này. Tạo trình xử lý trong Hoạt động, Chuyển đối tượng xử lý này cho mỗi AsyncTask. Trong cuộc gọi onPost handler.sendEmptyMessage (CONSTANT_INT); Trong Handler handleMessage kiểm tra msg.what nhập nếu hoặc chuyển Bằng cách này chỉ có một đối tượng điều khiển sẽ được tạo ra và được sử dụng trong nhiều kêu gọi async từ một hoạt động

+0

Bạn có thể mô tả những gì bạn nghĩ là đối tượng định hướng về cách tiếp cận của bạn? Trích dẫn OP: _Điều gì sẽ là hướng đối tượng theo cách thức ra trường hợp này? _ –

4

Thêm một biến thành viên cho cả lớp AsyncTask tức,

public class GettingBeaconsList extends AsyncTask<String, String, String> 
public class GettingAirports extends AsyncTask<String, String, String> 

như

private int flag; 

và viết setter cho rằng như

public void setFlag(int flag) 
{ 
    this.flag = flag; 
} 

Trong MainClass:

GettingBeaconsList beaconsList = new GettingBeaconsList(context,MainClass.this); 
beaconsList.setFlag(100); //Declare this flag in integer constant. 
beaconsList.execute(); 

GettingAirports airports = new GettingAirports(context, MainClass.this); 
airports.setFlag(200); 
airports.execute(); 

Trong Cả lớp AsyncTask vượt qua cờ với phương pháp của đại biểu: -

protected void onPostExecute(String file_url) 
{   
    pDialog.dismiss();  
    delegate.JsonArrayLoaded(gotNearestbeacons, flag); 
    //Change the signature of this method 
} 

Một lần nữa trong MainClass để xử lý phản ứng: -

@Override 
public void JsonArrayLoaded(JSONArray result, int flag) 
{ 

    // Here check which Background task has been completed 
    if(flag == 100) // GettingBeaconsList is executed 

    if(flag == 200) // GettingAirport is executed. 


    // bla bla or whatever here i write, does not matter 
    if(ServiceBoolean == 1) { 
      // Load activity 5 
    } 

    else if(ServiceBoolean == 2) 
    { 
     // Load activity 6 

    } 

    else if(ServiceBoolean==3) 
    { 
     // display Toast or Alert Box or load Activity number 8 
    } 


} 
+0

Nếu tôi hiểu vấn đề của bạn một cách chính xác thì điều này sẽ giúp bạn ra ngoài. Chúc may mắn. –

+0

Bạn có thể mô tả những gì bạn nghĩ là đối tượng định hướng về cách tiếp cận của bạn?Trích dẫn OP: _Điều gì sẽ là cách hướng đối tượng ra trường hợp này? _ –

0

Tôi đề nghị bạn chỉ cần sử dụng n lớp bên trong cho Hoạt động của bạn triển khai DelegateTaskCompleted. Nó đơn giản, hiệu quả, rõ ràng và dễ hiểu (suy nghĩ bảo trì) - và bạn đang chuyển giao cho người được ủy quyền khi bạn xây dựng AsyncTask của mình, vậy bạn có thể có cách tiếp cận này trong tâm trí mình không?

public class MainClass extends Activity { 
    // probabnly not static ;) 
    private final class BeaconsDelegate implements DelegateTaskCompleted ... 
    private final class AirportsDelegate implements DelegateTaskCompleted ... 
}