2013-01-10 35 views
10

嗯,我有與已經在兩個獨立的類定義了像一個接口如何用於不同的背景android任務?

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

被初始化,並在執行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 
     } 


    } 

} 

兩個後臺任務(異步任務)的活動類現在在上面的代碼MainClass.this被存儲爲AsynTask子接口中的接口引用這樣的子類

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; 
} 
每個AsynTask類別或亞類的

onPostExecute,JSONArray返回或傳回給調用的類,如下所示。在這種情況下調用類是MainClass但也有它們使用相同的AsynTask類其他活動類(GettingBeaconsListGettingAirports

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

現在我在有一個方法(JsonArrayLoaded)MainClass解決來自兩個不同背景任務或服務的兩個響應。我正在使用條件來確定執行哪個服務/類或AsynTask。

但我要求解決這樣的場景,就好像我們在未來的5個或更多的後臺服務,他們也只是返回一個JSON陣列所以,我需要做獨立的接口爲每個服務的最佳方式是什麼?

什麼應該是面向對象的出路這種情況?

+2

接口的名稱也不正確。發佈示例時請遵循適當的命名約定。 –

+2

在Main類中使用了哪個結果?請編輯帖子並舉例說明。沒有意義 –

+1

@MuhammadIrfan因此,對於你面向_object方向的問題來解決你的問題,你選擇了最不面向對象的答案?我會說這很酷。 :) –

回答

7

最簡單的解決方案,我能想到的是修改DelegateTaskCompleted接口,因此它看起來像這樣:最後

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

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

然後你onPostExecute將自己送回像下面,在您的MainClass中,您可以根據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 
     } 

    } 

這樣你可以容易地識別出經過上述應答發送,而不必跟蹤其是,如果一個所需的時間比其他長等


可選地,AsyncTask,具有延伸AsyncTask但增加另一個類一個用於識別的抽象變量。

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 
} 

然後讓你的機場和信標AsycTasks延長這個代替。這將要求他們實施getId方法。

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

然後,而不是做一個有條件if (task instanceof GettingAirports)你可以做一個switch聲明如下圖所示:

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

希望這有助於。

+0

你能描述一下你認爲面向對象的方法嗎?引用OP:_什麼是面向對象的方式?_ –

6

如果我正確理解你的問題,你已經延長的AsyncTask若干次。這些子類中的每一個的目標都是將JSONArray傳遞給實現DelegateTaskCompleted的Activity,在那裏你可以做些什麼。挑戰在於你想對這個JSONArray做的「事情」根據AsyncTask生成它的不同而不同。

去關閉這些假設,有很多不同的方法可以區分哪些的AsyncTask的JSONArray來自何處:

  1. 創建一個靜態變量,如int,在DelegateTaskCompleted類文件爲每種類型的JSONArray的它需要處理。向此變量的同一類型的JsonArrayLoaded添加一個參數。然後,使用if-else語句或switch語句來檢查該變量,並根據該語句對您的JSONArray執行操作。
  2. 如果你有機會獲得無論是生成JSONArray,使0 index數組包含的信息,如何解析它。 (也許你可以用if-else或switch來比較一下)
  3. 正如你所建議的,爲每個AsyncTask創建一個單獨的接口,或者使用多個方法創建一個單獨的接口。

只有選項3是一個面向對象的解決方案,正如在評論中指出的那樣,由於可伸縮性而不是很好的解決方案。這絕不是一個完整的清單,只是我的一些想法。

我想知道,不過,如果它的價值在所有,或呈現的方式至少使用接口。由於你已經有了AsyncTask的不同子類來處理JSONArrays的生成,爲什麼不在你的主線程的doInBackground()方法中做任何你正在做的事情,或者至少把邏輯放在這些類的某個地方,返回結果(或者可能將它們填入數據庫並在需要時得到它們)。我在想,可能有更好的方法來處理你的AsyncTask繼承,它可以避免所有的接口在一起,或者至少以不同的方式使用它們,比如所有的AsyncTasks都實現一個接口。

如果您能澄清您的問題並解釋AsyncTasks和您的方法正在執行的操作類型,並且可能您按照您的方式使用接口的原因,那將非常有幫助。很難給出關於面向對象最佳實踐的具體面向對象的答案或建議,只需要很少的信息就能知道你的代碼實際正在做什麼並希望實現。

+0

我在doInBackground()中以json格式從數據庫提取記錄。不同的AysnTask將不同的記錄作爲JSONArray獲取。 –

+0

使用接口是因爲還有其他活動類使用相同的AsynTask,以便使AsynTask具有通用性。 onPostExecute方法,我使用了delegate.JsonArrayLoaded(gotNearestbeacons);委託是代表這裏所有活動類的接口。 –

+0

JSONArrayLoaded執行不同的操作。我在這一部分修改了一個問題 –

12

嗨這段代碼將幫助您

這是回調接口

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

} 

使用的AsyncTask類爲抽象類

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); 
    } 
} 
} 

並在代碼中使用這樣的

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); 

你可以用這種方式重用代碼,我希望這會對你有所幫助。提前致謝。

6

你也可以考慮處理程序來實現這一點。 在Activity中創建處理程序, 將此處理程序對象傳遞給每個AsyncTask。 在onPost調用handler.sendEmptyMessage(CONSTANT_INT); 在處理程序的handleMessage在如果檢查 msg.what或切換 這種方式處理的只有一個對象將從一個活動

+0

您能描述一下您認爲面向對象的方法嗎?引用OP:_什麼應該以面向對象的方式出現在這種情況下?_ –

4

被創建和多個內用於異步 呼叫添加一個成員變量兩者的AsyncTask類,即,

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

private int flag; 

寫爲二傳手作爲

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

在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(); 

在兩者的AsyncTask類通過標誌與委託的方法,包括: -

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

再在MainClass處理響應: -

@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

如果我正確理解你的問題,那麼這將幫助你。祝你好運。 –

+0

你能描述一下你認爲面向對象的方法嗎?引用OP:_什麼是面向對象的解決方案?_ –

0

我建議你只需使用n個內部類爲您的活動執行DelegateTaskCompleted。它很簡單,高效,清晰易懂(想想維護) - 並且在構建AsyncTasks時已經傳遞了委託,那麼您是否已經有了這種方法?

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