2016-10-29 4 views
1

Я проанализировал некоторые данные в Asynctask и распечатал их в журнале, но всякий раз, когда я пытаюсь скопировать ArrayList данных в свою активность, он всегда остается равным нулю.Получение Arraylist из внутреннего класса AsyncTask

Вот код,

public class MainActivity extends AppCompatActivity { 

    static ArrayList<NewsItems>myData=new ArrayList<>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ReadRss readRss = new ReadRss(this); 
     readRss.execute(); 
     Log.d("TAG", String.valueOf(myData.size()));//This stays empty 
    } 


    public static void getData(ArrayList<NewsItems>items){ 
     for (int i=0; i<items.size(); i++){ 
      myData.add(items.get(i)); 
     } 
    } 
    class ReadRss extends AsyncTask<Void, Void, Void>{ 

     ArrayList<NewsItems>feedItems = new ArrayList<>(); 
     Context context; 
     String address = "http://www.thedailystar.net/frontpage/rss.xml"; 
     ProgressDialog progressDialog; 
     URL url; 

     public ReadRss(Context context) { 
      this.context = context; 
      progressDialog = new ProgressDialog(context); 
      progressDialog.setMessage("Loading..."); 
     } 

     @Override 
     protected void onPreExecute() { 
      if(progressDialog!=null){ 
       if (!progressDialog.isShowing()){ 
        progressDialog.show(); 
       } 
      } 
      super.onPreExecute(); 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      if(progressDialog!=null){ 
       if (progressDialog.isShowing()){ 
        progressDialog.hide(); 
       } 
      } 
      MainActivity.getData(feedItems); 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 
      ProcessXml(Getdata()); 
      return null; 
     } 

     private void ProcessXml(Document data) { 

      if (data != null) { 

       Element root = data.getDocumentElement(); 
       Node channel = root.getChildNodes().item(1); 
       NodeList items = channel.getChildNodes(); 
       for (int i = 0; i < items.getLength(); i++) { 
        Node currentchild = items.item(i); 
        if (currentchild.getNodeName().equalsIgnoreCase("item")) { 
         NewsItems item=new NewsItems(); 
         NodeList itemchilds = currentchild.getChildNodes(); 
         for (int j = 0; j < itemchilds.getLength(); j++) { 
          Node current = itemchilds.item(j); 
          if (current.getNodeName().equalsIgnoreCase("title")){ 
           item.setTitle(current.getTextContent()); 
          }else if (current.getNodeName().equalsIgnoreCase("description")){ 
           item.setDescription(current.getTextContent()); 
          }else if (current.getNodeName().equalsIgnoreCase("media:thumbnail")){ 
           item.setMedia(current.getAttributes().getNamedItem("url").getTextContent()); 
          }else if (current.getNodeName().equalsIgnoreCase("link")){ 
           item.setUrl(current.getTextContent()); 
          } 
         } 
         feedItems.add(item); 
         Log.d("itemTitle", item.getTitle()); 
         Log.d("itemDescription",item.getDescription()); 
         Log.d("itemMediaLink",item.getMedia()); 
         Log.d("itemLink",item.getUrl()); 

        } 
       } 
      } 

     } 



     public Document Getdata() { 
      try { 
       url = new URL(address); 
       HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
       connection.setRequestMethod("GET"); 
       InputStream inputStream = connection.getInputStream(); 
       DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 
       DocumentBuilder builder = builderFactory.newDocumentBuilder(); 
       Document xmlDoc = builder.parse(inputStream); 
       return xmlDoc; 
      } catch (Exception e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 

    } 

} 

Я попытался назвать статический метод деятельности в методе onPostExecute, он не работает.

+0

Что не работает? Где вы используете данные? –

ответ

5

1) Вы должны объявить переменную ArrayList в качестве члена mainActivity и , а затем передать ее ссылку в Asynctask.

2) Вы можете проверить, что данные присутствуют в списке, только после того, как вы убедитесь, что Asynctask завершила обработку. (Вы можете сделать это в пределах onPostExecute AsyncTask).

public class MainActivity extends AppCompatActivity { 

ArrayList<NewsItems>myData=new ArrayList<>(); //No need for static 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    ReadRss readRss = new ReadRss(this,myData); //Pass the list variable reference into the asynctask instance 
    readRss.execute(); 
    Log.d("TAG", String.valueOf(myData.size()));//This will be empty due to concurrent call to asynctask, which executes parallel to main thread. 
} 


public void getData(ArrayList<NewsItems>items){//Static qualifier unneccessary here 
    for (int i=0; i<items.size(); i++){ 
     myData.add(items.get(i)); 
    } 
} 
class ReadRss extends AsyncTask<Void, Void, Void>{ 

    ArrayList<NewsItems>feedItems = new ArrayList<>(); 
    Context context; 
    String address = "http://www.thedailystar.net/frontpage/rss.xml"; 
    ProgressDialog progressDialog; 
    URL url; 

    public ReadRss(Context context,ArrayList<NewsItems> feedItems) { 
     this.context = context; 
     this.feedItems = feedItems; //Assign the reference of the list here so that modifications done within the Asynctask are reflected in the MainActivity 
     progressDialog = new ProgressDialog(context); 
     progressDialog.setMessage("Loading..."); 
    } 

    @Override 
    protected void onPreExecute() { 
     if(progressDialog!=null){ 
      if (!progressDialog.isShowing()){ 
       progressDialog.show(); 
      } 
     } 
     super.onPreExecute(); 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     if(progressDialog!=null){ 
      if (progressDialog.isShowing()){ 
       progressDialog.hide(); 
      } 


     } 
    //Do whatever you need with the arraylist data here 
     getData(feedItems); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     ProcessXml(Getdata()); 
     return null; 
    } 
+0

, но ArrayList myData должен быть статичным, потому что я использую это в статическом методе ниже. Должен ли я удалить статику из метода? – Mufad

+0

@Mufad: Да, статический префикс в этом сценарии кажется необработанным. Метод не обязательно должен быть статическим. Вы можете вызвать этот метод в AsyncTask без префикса его с помощью MainActivity – SoulRayder

+0

@Mufad: Пожалуйста, примите ответ, если вы удовлетворены. Еще раз, дайте мне знать, если вам нужны дополнительные разъяснения. – SoulRayder

1

Избегайте использования статических переменных как можно больше. Ненужные статические поля вызывают проблемы, которые трудно понять.

Если вы заселяете его в AdapterView, например ListView, не забудьте позвонить adapter.notifyDataSetChanged(), когда у вас есть набор данных, готовый к вам.

Фактически вы можете передать результат своего doInBackground() на номер onPostExecute(), чтобы продолжить работу над вызывающей нитью, которая является основной нитью в вашем случае.

new AsyncTask<Void, Void, ArrayList<NewsItems>>() { 
    @Override 
    protected ArrayList<NewsItems> doInBackground(Void... params) { 
     ArrayList<NewsItems> response = whatEverMethodGetsMeNetworkCallResponse(); 

     return response; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<NewsItems> response) { 
     super.onPostExecute(response); 

     // Do whatever you want to do with the network response 
    } 
}.execute(); 

Или вы даже можете настроить слушателей и сделать это в более сложный способ, как:

onCreate() { 
    ... 

    getNewsItems(new NewsItemsListener() { 
     void onFetched(ArrayList<NewsItems> items) { 
      // Do whatever you want to do with your news items 
     } 
    }); 
} 

public void getNewsItems(final NewsItemsListener listener) 
    new AsyncTask<Void, Void, ArrayList<NewsItems>>() { 
     @Override 
     protected ArrayList<NewsItems> doInBackground(Void... params) { 
      ArrayList<NewsItems> response = whatEverMethodGetsMeNetworkCallResponse(); 

      return response; 
     } 

     @Override 
     protected void onPostExecute(ArrayList<NewsItems> response) { 
      super.onPostExecute(response); 

      listener.onFetched(response); 
     } 
    }.execute(); 
} 

public interface NewsItemsListener { 
    void onFetched(ArrayList<NewsItems> items); 
} 
Смежные вопросы