我已在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的静态方法,它不起作用。
答案 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();