从内部AsyncTask类获取Arraylist

时间:2016-10-29 06:06:33

标签: java android arraylist android-asynctask

我已在XML中解析了一些Asynctask数据并将其打印在日志中,但每当我尝试将ArrayList数据复制到我的活动中时,它始终保持不变空。

这是代码,

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方法中调用Activity的静态方法,它不起作用。

2 个答案:

答案 0 :(得分:5)

1)您应该将ArrayList变量声明为mainActivity的成员,然后将其引用传递给Asynctask。

2)只有在确定Asynctask已完成处理后,才能验证数据是否存在于列表中。 (您可以在AsyncTask的 onPostExecute 中执行此操作。)

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

答案 1 :(得分:1)

尽可能避免使用静态变量。不必要的静态字段使您陷入难以理解的问题。

如果您使用<?php function your_shipping_method_init() { if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) { class WC_Your_Shipping_Method extends WC_Shipping_Method { /*---------------------------------------------------------------- Constructor for your shipping class ----------------------------------------------------------------*/ public function __construct() { $this->id = 'your_shipping_method'; // Id for your shipping method. Should be uunique. $this->method_title = __( 'Your Shipping Method' ); // Title shown in admin $this->method_description = __( 'Description of your shipping method' ); // Description shown in admin $this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled $this->title = "My Shipping Method"; // This can be added as an setting but for this example its forced. $this->init(); } /*---------------------------------------------------------------- Init your settings ----------------------------------------------------------------*/ function init() { // Load the settings API $this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings $this->init_settings(); // This is part of the settings API. Loads settings you previously init. // Save settings in admin if you have any defined add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); } /*---------------------------------------------------------------- calculate_shipping function. ----------------------------------------------------------------*/ public function calculate_shipping( $package ) { global $woocommerce; $carttotal = $woocommerce->cart->cart_contents_count; /* 1-5 packs 5,000 6-10 packs 10,000 11-15 packs 15,000 16-20 packs 20,000 */ if($carttotal > 20){ $cost = 0;//Free delivery for above 20 packs }else if($carttotal >= 16 && $carttotal <= 20){ $cost = 20000; }else if($carttotal >= 11 && $carttotal <= 15){ $cost = 15000; }else if($carttotal >= 6 && $carttotal <= 10){ $cost = 10000; }else if($carttotal <= 5 && $carttotal >= 1){ $cost = 5000; } $rate = array( 'id' => $this->id, 'label' => 'Shipping', 'cost' => $cost, ); // Register the rate $this->add_rate( $rate ); } } } } add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' ); function add_your_shipping_method( $methods ) { $methods['your_shipping_method'] = 'WC_Your_Shipping_Method'; return $methods; } add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' ); 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();
相关问题