2016-09-22 103 views
-3

I Googled很多,但沒有這個機會。 現在,我有一個Inner AsyncTask類,我想使用上層類中的返回值。 它成功地工作,因爲我已經把Log.e(),它顯示了自己的價值,這是我的代碼:從void AsyncTask返回ArrayList

public class Consume extends AsyncTask<Void, Void, Void> { 
     private List<LatLng> latLngs = new ArrayList<>(); 
     private List<ContactModel> contacts = new ArrayList<>(); 
     InputStream inputStream = null; 
     String result = ""; 

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

      String URL = "http://x.x.x.x/MYWCF/Service1.svc/Json/getContact"; 
      ArrayList<NameValuePair> param = new ArrayList<NameValuePair>(); 
      try { 
       HttpClient httpClient = new DefaultHttpClient(); 
       HttpPost post = new HttpPost(URL); 
       post.setEntity(new UrlEncodedFormEntity(param)); 
       HttpResponse httpResponse = httpClient.execute(post); 
       HttpEntity httpEntity = httpResponse.getEntity(); 
       inputStream = httpEntity.getContent(); 

      } catch (UnsupportedEncodingException e1) { 
       Log.e("UnsupportedEncoding", e1.toString()); 
       e1.printStackTrace(); 
      } catch (ClientProtocolException e2) { 
       Log.e("ClientProtocolException", e2.toString()); 
       e2.printStackTrace(); 
      } catch (IllegalStateException e3) { 
       Log.e("IllegalStateException", e3.toString()); 
       e3.printStackTrace(); 
      } catch (IOException e4) { 
       Log.e("IOException", e4.toString()); 
       e4.printStackTrace(); 
      } 
      try { 
       BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8); 
       StringBuilder sBuilder = new StringBuilder(); 

       String line = null; 
       while ((line = bReader.readLine()) != null) { 
        sBuilder.append(line + "\n"); 
       } 
       inputStream.close(); 
       result = sBuilder.toString(); 
      } catch (Exception e) { 
       Log.e("StringBuilding", "Error converting result " + e.toString()); 
      } 
      return null; 
     } 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      List<ContactModel> contactModels; 
      List<LatLng> myLatLngs = new ArrayList<>(); 
      try { 

       JSONObject object = new JSONObject(result); 
       JSONArray jArray = object.getJSONArray("getContactResult"); 

       Type listType = new TypeToken<List<ContactModel>>() { 
       }.getType(); 
       contactModels = new Gson().fromJson(String.valueOf(jArray), listType); 
       setContacts(contactModels); 

       setContacts(contactModels); 
       for(ContactModel contactModel : contactModels) { 
        Double latitude = Double.valueOf(contactModel.getLatitude()); 
        Double longitude = Double.valueOf(contactModel.getLongitude()); 
        LatLng latLong = new LatLng(latitude, longitude); 
        myLatLngs.add(latLong); 
       } 
       setLatLngs(myLatLngs); 
       Log.e("SizeOfArray", myLatLngs.size()+""); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 

    public void setContacts(List<ContactModel> contacts) { 
     this.contacts = contacts; 
    } 

    public List<ContactModel> getContacts() { 
     return contacts; 
    } 

    public void setLatLngs(List<LatLng> latLngs) { 
     this.latLngs = latLngs; 
    } 
    public List<LatLng> getLatLngs() { 
     return latLngs; 
    } 

在我Activity Class

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.osmdroid_map); 


    Consume consume = new Consume(); 
    consume.execute(); 

當我運行該應用程序,原因行:

   Log.e("SizeOfArray", myLatLngs.size()+""); 

它返回我數組大小的正確INT數logcat,但我想用在我的應用程序, 我甚至在doInBackground方法裏做了所有的東西,甚至做了一個static變量, 沒機會。 任何人都可以通過我的代碼提供真實樣本嗎? Thx

+0

在'onPostExecute'中調用一個函數並將myLatLngs.size()傳遞給它,然後執行你打算做的任何事情。 – Alamri

+0

我做到了這一點,沒有機會,我傳遞了整個數組,因爲我需要整個數組。 我做了set setContacts(ArrayListOfContactModel),然後在我的onCreate中調用如下:consume.getContacts(); 沒有運氣。 –

+0

如果我可能會問你打算在myLatLngs.size()中使用什麼? – Alamri

回答

0

THX一切,爲了一切的答覆。 Thx,我真的不明白問題是什麼,並且是因爲我問了這個簡單的問題!不幸的是你們沒有人注意到這一點。 代碼後:

Consume consume = new Consume(); 
consume.execute(): 

編譯器去太執行下一個代碼,原因consume.execute()啓動另一個線程,但主線程繼續。 原因是我收到我想要的延遲值,因此我雖然問題是如何獲得值,但實際上問題是我無法處理線程異步。 所以我把它們全部移到了onPreonPost方法的AsyncTask類,然後它就起作用了!

0

首先,我會說你應該使用靜態內部類而不是非靜態內部類來避免內存泄漏,因爲非靜態內部類保存對外部類的引用。另一件事是,你可以通過外父類的WeakReference這樣就可以從的AsyncTask的onPostExecute()返回值一樣

public static class Consume extends AsyncTask<Void, Void, Void> { 

    WeakReference<MainActivity> mActivity; 

    public Consume(MainActivity activity){ 
     mActivity = new WeakReference<SampleActivity>(activity); 
    } 
} 

在你的AsyncTask的onPostExecute方法,這將是

mActivity.response(latLngs); 

而在你的其他類就會像

private static void response(List<LatLng> latLngs){ 
    // handle response here in your outer class 
} 

更新Here是如何將活動的WeakReference傳遞給Inner或Anonymous類並使用它。

+0

你是什麼意思的activity.response(latLngs); 這裏有什麼活動? –

+0

@T_O它的WeakReference實例! –

+0

@T_O我更新了我的僞代碼! –

0

只要你的AsyncTask類是一個內部類。它可以直接訪問外部類的對象。

在您的外部級別級別創建以下對象。

List<LatLng> myLatLngs = new ArrayList<>(); 

並從內部類相同,這樣一個對象實例將是他們的。

另一種方法是使用內部asyntask的回調函數,您需要將接口回調函數傳遞給外部類以開始進一步處理。

interface CallBack { 
    public void processingDone(); 
} 

Consume consume = new Consume(new CallBack() { 
    @Override 
    public void processingDone(List<LatLng> mLatLngs) { 
    // Do your stuff here 
    } 
}); 
consume.execute(); 

並且在你的Consume構造函數存儲區回調函數中將數據傳回給外部類。

class Consume { 
    private Callback mCallback; 
    public Consume(Callback callback) { 
    mCallback = callback; 
    } 
} 

而且從下面的鏈接,你可以做

if (mCallback != null) { 
    mCallback.processingDone(myLatLngs); 
} 
Log.e("SizeOfArray", myLatLngs.size()+"");